Как получить точный SQL-запрос, содержащий исключение при пакетной обработке
Я хочу выполнить следующее:
(перевод в БД ПРЕЗЕНТАЦИИ строки из выбранной строки БД ОБРАБОТКИ)
PreparedStatement stmt;
Statement st;
Connection conn = ConnectionManager.getInstance().getConnection(ConnectionManager.PRESENTATION_DB);
try {
conn.setAutoCommit(false);
stmt = conn.prepareStatement(
"insert into customer (name,category,age) values (?,?,?)");
stmt.clearParameters();
stmt.setString(1,"name2");
stmt.setString(2,"cat2");
stmt.setInt(3,25);
stmt.addBatch();
stmt.clearParameters();
stmt.setString(1,"name3");
stmt.setString(2,"cat3");
stmt.setInt(3,25);
stmt.addBatch();
stmt.clearParameters();
stmt.setString(1,"name4");
stmt.setString(2,"cat2");
stmt.setInt(3,25);
stmt.addBatch();
stmt.clearParameters();
stmt.setString(1,"name4");
stmt.setString(2,"cat2");
//stmt.setInt(3,25);
//this is parameter with false input
stmt.setString(3,"null");
stmt.addBatch();
stmt.clearParameters();
stmt.setString(1,"name5");
stmt.setString(2,"cat5");
stmt.setInt(3,25);
stmt.addBatch();
stmt.clearParameters();
int [] updateCounts = stmt.executeBatch();
conn.commit();
conn.setAutoCommit(true);
stmt.close();
conn.close();
}
catch(BatchUpdateException b) {
System.err.println("-----BatchUpdateException-----");
System.err.println("SQLState: " + b.getSQLState());
System.err.println("Message: " + b.getMessage());
System.err.println("Vendor: " + b.getErrorCode());
System.err.print("Update counts: ");
int [] updateCounts = b.getUpdateCounts();
for (int i = 0; i < updateCounts.length; i++) {
System.err.print(updateCounts[i] + " ");
}
System.err.println("");
}
catch (Exception e) {
e.printStackTrace();
}
Как определить строку, из-за которой исключение смогло повторно выполнить пакетную обработку без этой конкретной строки? (Путем обновления поля строки hasError).
В настоящее время я не сохраняю объекты в пакетном режиме, поэтому могу пометить строку, если она вызывает ошибку, пропустить эту строку и перейти к обработке (т.е. сохранить / передать и удалить) другой строки.
Спасибо!
Обновить:
Хорошо, я использовал следующий код для отслеживания строк (если какая-либо строка вызывает ошибку):
public static void processUpdateCounts(int[] updateCounts) {
for (int i=0; i<updateCounts.length; i++) {
if (updateCounts[i] >= 0) {
// Successfully executed; the number represents number of affected rows
logger.info("Successfully executed: number of affected rows: "+updateCounts[i]);
} else if (updateCounts[i] == Statement.SUCCESS_NO_INFO) {
// Successfully executed; number of affected rows not available
logger.info("Successfully executed: number of affected rows not available: "+updateCounts[i]);
} else if (updateCounts[i] == Statement.EXECUTE_FAILED) {
logger.info("Failed to execute: "+updateCounts[i]);
// Failed to execute
}
}
}
И добавил строку:
processUpdateCounts(updateCounts);
так что я могу видеть изменения с ошибкой или без нее, но похоже, что BatchUpdateException не работает?
4 ответа
Создайте слой БД, который поможет выполнить команду. Если команда sql не удалась, повторите ее несколько раз, используя цикл while или что-то еще, если по-прежнему не удалось через несколько раз, зарегистрируйте ее.
Как уже указывалось, вы получаете доступ только к индексу оператора SQL, который потерпел неудачу во время пакета. Это означает, что для воссоздания того же оператора, который не удалось выполнить, вы должны хранить параметры индексируемым способом, например:
List<...>paramList = new ArrayList<...>();
for (... params in paramList) {
stmt.clearParameters();
stmt.setString(...something involving params...);
// etc.
}
Таким образом, индекс getUpdateCounts
с EXECUTE_FAILED
Массив можно использовать для определения того, какие параметры вызвали сбой.
Я использую mysql-connector-java-3.1.14 с MySQL. Обновление в верхней части этого раздела (которое использует исключение BatchUpdateException и getUpdateCounts) работает правильно. Теперь я могу найти проблемную строку в пакетной вставке / обновлении.
Цитаты из Javadoc BatchUpdateException:
Порядок элементов в массиве счетчиков обновлений соответствует порядку, в котором команды были добавлены в пакет.
После того, как команда в пакетном обновлении не выполняется должным образом и генерируется исключение BatchUpdateException, драйвер может или не может продолжать обрабатывать оставшиеся команды в пакете. Если драйвер продолжает обработку после сбоя, массив, возвращенный методом BatchUpdateException.getUpdateCounts, будет иметь элемент для каждой команды в пакете, а не только элементы для команд, которые успешно выполнялись до ошибки. В случае, когда драйвер продолжает обрабатывать команды, элементом массива для любой неудачной команды является Statement.EXECUTE_FAILED.