Ошибка утверждения при выполнении PreparedStatement с использованием Oracle thin JDBC

#java #oracle #jdbc

#java #Oracle #jdbc

Вопрос:

Я столкнулся с любопытной (похожей на a) ошибкой с PreparedStatements с использованием драйвера Oracle thin JDBC (ojdbc7). Ошибка утверждения возникает при многократном выполнении PreparedStatement и, по-видимому, связана с установкой значений привязки null.

Вот выдержка из тестового кода, которая демонстрирует это:

   private void insertRows(String tableName) throws SQLException
  {
    String insertSQL = 
      "INSERT INTO "
            tableName
            " (objectid, attributeid, sequence, value)"
            " VALUES (?, ?, ?, ?)";
    PreparedStatement stmt = m_Conn.prepareStatement(insertSQL);
    
    // insert first 3 rows with same objId and attrId
    long objId = 700;
    long attrId = 701;
    int seq = 1;

    stmt.setLong(1, objId);
    stmt.setLong(2, attrId);

    // 1st row (non-null value)
    stmt.setInt(3, seq  );
    stmt.setString(4, "Foo");
    stmt.execute();

    // 2nd row (null value)
    stmt.setInt(3, seq  );
    stmt.setNull(4, Types.VARCHAR);
    stmt.execute();

    // 3rd row (null value)
    stmt.setInt(3, seq  );
    stmt.setNull(4, Types.VARCHAR);
    stmt.execute();

    // insert next 2 rows with new objId and attrId
    objId = 800;
    attrId = 801;
    seq = 1;

    stmt.setLong(1, objId);
    stmt.setLong(2, attrId);

    // 1st row (null value)
    stmt.setInt(3, seq  );
    stmt.setNull(4, Types.VARCHAR);
    stmt.execute();

    // 2nd row (non-null value)
    stmt.setInt(3, seq  );
    stmt.setString(4, "Bar");
    stmt.execute();  // this results in an AssertionError

    System.out.println("Inserts were successful");
    stmt.close();
  }
  

5-е выполнение PreparedStatement приводит к ошибке утверждения:

 Expected AssertionError: java.lang.AssertionError: lastOffset: 5        leastOffset: 5  indexOfLeastOffet: 3
java.lang.AssertionError: lastOffset: 5 leastOffset: 5  indexOfLeastOffet: 3
        at oracle.jdbc.driver.OraclePreparedStatement.compressLastBoundData(OraclePreparedStatement.java:1902)
        at oracle.jdbc.driver.OraclePreparedStatement.setupDbaBindBuffers(OraclePreparedStatement.java:3062)
        at oracle.jdbc.driver.OraclePreparedStatement.setupBindBuffers(OraclePreparedStatement.java:3046)
        at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2670)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4790)
        at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:4901)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1385)
        at oracle.Dave.Bug912.insertRows(Bug912.java:130)
        at oracle.Dave.Bug912.main(Bug912.java:38)

  

Ошибка утверждения возникает только при определенных комбинациях параметров привязки значений и, по-видимому, связана с установкой значений null (ошибка не возникает, если значения null не используются). Это также не происходит при отключенных утверждениях (очевидно). Версия базы данных, похоже, не имеет значения — я видел это как для 11.2, так и для 12.1.

Кто-нибудь видел такую ошибку раньше? Я могу приложить полный тестовый пример, если кому-то интересно.

Комментарии:

1. можете ли вы попробовать executeUpdate()

2. Тот же результат с executeUpdate() .

3. Какую версию Oracle (пожалуйста, полные версии!) Вы используете и какую версию драйвера Oracle JDBC (ojdbc7 не является версией, это указывает, что она предназначена для Java 7).

4. Версия драйвера: Oracle 12.1.0.2.0 JDBC 4.1, скомпилированная с помощью JDK7 в Mon_Jun_30_11:30:34_PDT_2014

5. Версия базы данных 12.1.0.2.0