java - 使用 Oracle 瘦 JDBC 执行 PreparedStatement 时出现 AssertionError
问题描述
我在使用 Oracle 的瘦 JDBC 驱动程序 (ojdbc7) 的 PreparedStatements 中遇到了一个奇怪的(看起来像一个)错误。多次执行 PreparedStatement 时会发生 AssertionError,并且似乎与设置空绑定值有关。
这是演示这一点的测试代码的摘录:
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();
}
PreparedStatement 的第 5 次执行导致 AssertionError:
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)
AssertionError 仅在绑定值设置的特定组合时出现,并且似乎与空值的设置有关(如果不使用空值,则不会出现该错误)。它也不会在禁用断言的情况下发生(显然)。数据库版本似乎无关紧要——我已经在 11.2 和 12.1 中看到了这一点。
有没有人见过这种错误?如果有人感兴趣,我可以附上一个完整的测试用例。
解决方案
推荐阅读
- vue.js - Vue.js 使用自定义类型的两种方式绑定
- javascript - 带有 ESCPOS 库的土耳其字符不起作用
- python - 给定任何纬度,经度。坐标,在列表中找到最近坐标的最快方法是什么?
- cassandra - PerSSTableIndexWriter.java:211 - 拒绝列有效负载的值(分析为假)
- alpacajs - 日期时间字段在 Alpaca.js 中不起作用
- docker - 配置 docker 容器以访问互联网和其他 docker 容器
- javascript - 是否有一个组合器的名称,它采用一个柯里化函数和一个元组并应用它们?
- c++ - 为什么使用整数类型约束 auto 会使 view::filter 无法调用它?
- javascript - 使用 JS 设置属性值,在每个值设置后清除 Python Selenium
- python-3.x - 在通过 ipywidgets 按钮单击调用函数后,有没有办法在变量中捕获函数的输出?