2014-09-24 3 views
-3

У меня есть следующий фрагмент кода:Как сделать этот JDBC-код более портативным?

List<List<Object>> batch = db.executeInsert("insert into Batches (batch_date,source,log_file,status) values (?, ?, ?, ?)", 
    now, 
    importZip.getAbsolutePath(), 
    logFile.getAbsolutePath(), 
    BatchStatus.IMPORTING.toString()) 

И возвращаемые данные, когда я запускаю его на MySQL возвращает целое число, представляющее вставленный ID, как и ожидалось. При запуске под Oracle он возвращает не переносимый объект ROWID. У меня есть столбец идентификаторов, который в конечном итоге будет преобразован в последовательность, которая представляет идентификатор. Однако с ROWID вы не можете многое сделать.

Я проверил код, и я звоню statement.getGeneratedKeys(), который, как я думал, составлял весь смысл создания портативного кода. Как я могу написать это в переносном режиме, не выполняя такие вещи, как select from table where ROWID=?, который явно НЕ переносится.

+0

Где находится метод 'db.executeInsert()'? Почему вы задаете вопросы о поведении кода, который вы еще не опубликовали? – EJP

ответ

1

Таким образом, переносимое решение, которое я нашел, должно было использовать несколько другую версию PreparedStatement и getGeneratedKeys() , Это оказалось, переносимых через как MySQL и Oracle, и я думаю, другие:

Connection connection = createConnection(); 
PreparedStatement statement = null; 
statement = connection.prepareStatement(sql,new String[] { "ID" }); 
int updateCount = statement.executeUpdate(); 

ResultSet keysRs = statement.getGeneratedKeys(); 
if(keysRs.next()) { 
    return keyRs.getInteger("ID"); 
} 

Это было решение, которое я использовал.

+0

Я немного удивлен, что это работает для Oracle, но хорошая находка! Поскольку я не знал, что эта функция работала над Oracle, я не упомянул об этом в своем ответе. –

1

Как вы уже узнали, Oracle возвращает ROWID, чтобы вы могли - например, получить идентификатор, запросив строку.

Некоторые базы данных возвращают только последний сгенерированный идентификатор (который может даже не принадлежать к столу, например, MySQL AFAIK), некоторые базы данных возвращают только столбец идентификатора, в качестве первого столбца в ResultSet, другие возвращают все столбцы (например, PostgreSQL, Firebird по умолчанию), поэтому позиция столбца id может быть не первой, поскольку она зависит от порядка столбцов в таблице.

Единственный реальный вариант - создать стратегию, специфичную для базы данных, которая знает правила для получения правильного столбца. Это может включать в себя отключение дополнительного запроса для Oracle, с некоторой эвристикой, чтобы найти столбец первичного ключа для PostgreSQL и Firebird и т. Д.

+0

Таким образом, под обложками кода executeInsert() он вызывает getGeneratedKeys(), который, как я думал, был механизмом независимой от поисковой DB-платформы. Почему вам все еще требуется написать конкретный код DB для обработки этой ситуации? Если это не так, то в чем смысл getGeneratedKeys()? – chubbsondubs

+0

@chubbsondubs В идеальном мире вам не нужно будет писать код DB, но это не идеальный мир, и просто есть различия в функциях, поддерживаемых базами данных. –

Смежные вопросы