当我在java中执行executeBatch方法时,它返回一个很好的int数组,但是所有数组元素的值都是-2,
它应该是0或+ ve数字,显示受影响的行数, 但它返回-2,
当我在数据库中检查时,所有更新都成功完成。 请解释这个-2的含义以及我如何找到受影响的行数。
感谢, Deepesh Uniyal
答案 0 :(得分:33)
jdbc-spec有关于批量更新的返回代码的以下内容:
■0或更高 - 命令已成功处理,值为a 更新计数,指示数据库中受影响的行数 命令的执行 第14章批量更新121
■Statement.SUCCESS_NO_INFO - 命令已成功处理, 但受影响的行数未知
Statement.SUCCESS_NO_INFO定义为-2,因此您的结果表明一切正常,但您无法获得有关更新列数的信息。
oracle-documentation指出:
• 对于准备好的语句批处理,无法通过批处理中的每个单独语句知道数据库中受影响的行数。因此,所有数组元素的值都为-2。根据JDBC 2.0规范,值-2表示操作成功但受影响的行数未知。
• 对于通用语句批处理,该数组包含实际更新计数,指示每个操作影响的行数。实际更新计数只能在Oracle标准批处理实现中的通用语句的情况下提供。
• 对于可调用语句批处理,服务器始终返回值1作为更新计数,而不管每个操作影响的行数。
因此,如果您需要更新计数,您似乎无法使用PreparedStatement
,但必须回归普通Statement
。
答案 1 :(得分:6)
值为-2表示已成功处理元素,但受影响的行数未知。
答案 2 :(得分:1)
请注意,从Oracle 12c开始,情况就不再适用了:
对于预准备语句批处理,该数组包含实际更新计数,指示每个操作影响的行数。
请参阅https://docs.oracle.com/database/121/JJDBC/oraperf.htm#JJDBC28773
答案 3 :(得分:0)
标准更新批处理...
conn.setAutoCommit(false);
PreparedStatement pstmt =
conn.prepareStatement("INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.addBatch();
pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch();
int[] updateCounts = pstmt.executeBatch();
conn.commit();
pstmt.close();
...
您可以处理更新计数数组以确定批处理是否成功处理。
Oracle标准批处理实施中的错误处理
如果任何一个批处理操作未能成功完成或尝试在executeBatch调用期间返回结果集,则处理将停止并生成java.sql.BatchUpdateException。
在批处理异常之后,可以使用BatchUpdateException对象的getUpdateCounts方法检索更新计数数组。这将返回一个int数组的更新计数,就像executeBatch方法一样。在标准更新批处理的Oracle实现中,处理批处理后,更新计数数组的内容如下:
对于准备好的语句批处理,如果出现错误 执行批处理时,executeBatch方法无法返回 值,而是抛出BatchUpdateException。在这种情况下, 异常本身携带一个大小为n的int数组作为其数据,其中n 是成功记录执行的次数。例如,如果 批量大小为5,错误发生在第4条记录,然后是 BatchUpdateException有一个大小为3的数组(执行3条记录 成功)并且数组中的每个项目表示行数 受到他们每个人的影响。
对于通用语句批处理或可调用语句批处理,更新
counts数组只是包含实际更新的部分数组
计算到错误点。实际更新计数可以是
因为Oracle JDBC不能使用真正的批处理来进行泛型和
Oracle标准更新执行中的可调用语句
配料。
例如,如果批处理中有20个操作,前13个成功,第14个生成异常,则更新计数数组将包含13个元素,包含成功操作的实际更新计数。
您可以根据需要在这种情况下提交或回滚成功的操作。
在您的代码中,处理批处理失败时,您应该准备好在发生异常时处理数组元素中的-3或真实更新计数。对于失败的批处理,您将具有-3的完整数组或正整数的部分数组。