Я пытаюсь написать логику для извлечения неудачных операторов после пакетного выполнения с использованием драйвера jdbc Oracle 12.1. Моя база данных - Oracle 11.2. Для моего тестирования я заставляю уникальное нарушение ограничения вызывать исключение BatchUpdateException. Однако batchUpdateException.getUpdateCounts возвращает -3 для всех операторов, даже если фактический сбой должен произойти в 3-й записи. Я ожидаю (-2, -2) или (1,1) для успешных записей в соответствии с документацией Oracle здесь: https://docs.oracle.com/en/database/oracle/oracle-database/12.2/jjdbc/performance-extensions.html#GUID-BF1E09C3-44A7-4CE9-A28A-BB01D5E335A9
Для подготовленного пакета операторов, в случаеошибка между выполнением пакета, метод executeBatch не может возвратить значение, вместо этого он генерирует исключение BatchUpdateException. В этом случае само исключение несет массив int размером n в качестве своих данных, где n - количество успешных выполнений записи. Например, если пакет имеет размер 5 и ошибка возникает в 4-й записи, то исключение BatchUpdateException имеет массив размера 3 (3 записи успешно выполнены), и каждый элемент в массиве представляет количество строк, затронутых каждой из них. .
Мой код здесь:
String sqlQuery = "insert into testbulk(id,name,age) VALUES (?,?,?)";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Properties info = new Properties( );
info.put( "user", USER );
info.put( "password", PASSWORD );
info.put("defaultBatchValue",20);
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:db", info);
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement(sqlQuery);
ps.setInt(1,1);
ps.setString(2, "Elana");
ps.setInt(3, 32);
ps.addBatch();
ps.setInt(1,1);
ps.setString(2, "Jocelyne");
ps.setInt(3, 45);
ps.addBatch();
ps.setInt(1,1);
ps.setString(2, "Bordie");
ps.setInt(3, 56);
ps.addBatch();
int[] affectedRecords = ps.executeBatch();
conn.commit();
ps.close();
}
catch(BatchUpdateException be) {
int[] updateCount = be.getUpdateCounts();
int count = 0;
for (int i : updateCount) {
if (i == Statement.EXECUTE_FAILED) {
System.out.println("Error on request " + count + ": Execute failed");
} else {
System.out.println("Request " + count + ": OK");
}
count++;
}
be.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
Я понимаю, что это не будет работать с любым jar ojbdc, более ранним, чем Версия 11 версии 1, поэтому я использовалверсия 12 банок. Но все еще не могу заставить его работать.
См. Документ Oracle: https://docs.oracle.com/database/121/JJDBC/oraperf.htm#JJDBC28767
До выпуска Oracle Database 11g Release 1 возвращаемый целочисленный массив содержит n Statement.EXECUTE_FAILEDзаписи, где n - размер пакета. Однако это не указывает, где в партии произошла ошибка. Единственный вариант - откат транзакции.
Начиная с Oracle Database 11g Release 1, возвращаемый целочисленный массив содержит n записей Statement.SUCCESS_NO_INFO, где n - количество успешно завершенных элементов в пакете. казнены.
Это работает для меня, если я использую заявление, но не с PreparedStatement, который мне нужен. Есть идеи? Заранее спасибо!