2014-11-17 2 views
4

У меня проблемы с этим.SQLException во время executeBatch(), когда я обрабатываю BatchUpdateException

Я пытаюсь перечислить некоторые данные о запросах, которые не были выполнены во время выполнения executeUpdate(), и я прочитал, что BatchUpdateException можно поймать, а затем получить updateCount, который сообщает вам, какие запросы выполнялись, а какие нет, но когда запрос терпит неудачу из-за плохого преобразования данных, он запускает SQLException, и я не могу поймать всю ошибку выполнения пакета.

Данные, необходимые для получения запросов из XML без каких-либо проверок.

Вот код:

try { 
    pSt_insertCabecera.executeBatch(); 
    } 
catch (BatchUpdateException buex){ 
    int[] updateCounts = buex.getUpdateCounts(); 
    for (int i = 0; i < updateCounts.length; i++) { 
     if (updateCounts[i] == Statement.EXECUTE_FAILED) { 
      logger.error(nombreClase + "[ESB_P]: Ha fallado la inserción de la cabecera de pedidos: " + cabecerasAInsertar.get(i).toString()); 
      throw new SQLException(); 
     } 
    } 
} 

SQLException выброшен кроме если это потому, что позже на код, который я поймать его, чтобы выполнить откат.

StackTrace выглядит следующим образом:

com.microsoft.sqlserver.jdbc.SQLServerException: Error al convertir una cadena de caracteres en fecha y/u hora. 
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatementBatch(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtBatchExecCmd.doExecute(Unknown Source) 
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unknown Source) 
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeBatch(Unknown Source) 

Я использую SQLServer 2012

Если вам нужно больше кода или информации, пожалуйста, обращайтесь.

Так много спасибо всем.

+0

, что является исключением, что вы получите? –

+0

Я получаю SQLException. Спасибо, что ответили так быстро! –

+0

Можете ли вы plz опубликовать свой стек? –

ответ

3

Я смог воссоздать вашу проблему. Для таблицы с именем [Клиенты] с datetime колонка с именем [DOB] код

String[] datesToApply = new String[] 
     { 
     "1978-12-31", 
     "junk", 
     "1981-11-11" 
     }; 

String sql = 
     "UPDATE Clients SET DOB=? WHERE ID=1"; 
try (PreparedStatement ps = conn.prepareStatement(sql)) { 
    for (String dt : datesToApply) { 
     ps.setString(1, dt); 
     ps.addBatch(); 
    } 
    int[] updateCounts = null; 
    try { 
     updateCounts = ps.executeBatch(); 
    } catch (BatchUpdateException bue) { 
     System.out.println("executeBatch threw BatchUpdateException: " + bue.getMessage()); 
     updateCounts = bue.getUpdateCounts(); 
    } catch (SQLException se) { 
     System.out.println("executeBatch threw SQLException: " + se.getMessage()); 
    } 
    if (updateCounts != null) { 
     for (int uc : updateCounts) { 
      System.out.println(uc); 
     } 
    } 
    if (!conn.getAutoCommit()) { 
     conn.commit(); 
    } 

бросает SQLException если AutoCommit выключен, но он бросает BatchUpdateException если AutoCommit включен. Осмотрев массив, возвращаемый .getUpdateCounts() показывает нам точку в партии, в которой первый сбой произошел

executeBatch threw BatchUpdateException: Conversion failed when converting date and/or time from character string. 
1 
-3 
-3 

, но он также показывает, что SQL Server «отдает» после первой неудачи. Кажется, нет возможности сказать SQL Server продолжить обработку оставшейся части пакета (например, continueBatchOnError для MySQL Connector/J).

Кроме того, поскольку AutoCommit «включен», обновления уже установлены, поэтому нет возможности откатить эти изменения. en masse. Если вы хотите, чтобы пакет был «все или ничего», вам нужно будет написать код, чтобы вернуться назад и отменить изменения, которые были успешно применены до первого сбоя.

(Другой вариант, конечно, проверить данные перед тем пытается поставить его в базу данных.)

+0

Спасибо, Горд!Оценивая, следует ли проверять данные перед выполнением обновлений или, в случае, когда генерируется SQLException, вызывается тот же метод, но с AutoCommit, установленным на «on», и выполнять те же операции и вставлять во временные таблицы, чтобы получить ошибки. Но я лично считаю лучший выбор для проверки до вставки, но они хотят быстро исправить, а не разработки ... –

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