Oracle JDBC: BatchUpdateException.getUpdateCounts не возвращает счетчик успеха с драйвером Oracle 12+ - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь написать логику для извлечения неудачных операторов после пакетного выполнения с использованием драйвера 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, который мне нужен. Есть идеи? Заранее спасибо!

...