【发布时间】:2013-10-02 01:31:40
【问题描述】:
当我在java中执行executeBatch方法时,它返回一个很好的int数组,但所有数组元素的值为-2,
它应该是 0 或 +ve 数字,表示受影响的行数, 但它返回 -2,
当我在数据库中检查它时,所有更新都成功完成。 请解释这个 -2 的含义以及我如何找到受影响的行数。
谢谢, Deepesh Uniyal
【问题讨论】:
-
写下你试过的代码......
当我在java中执行executeBatch方法时,它返回一个很好的int数组,但所有数组元素的值为-2,
它应该是 0 或 +ve 数字,表示受影响的行数, 但它返回 -2,
当我在数据库中检查它时,所有更新都成功完成。 请解释这个 -2 的含义以及我如何找到受影响的行数。
谢谢, Deepesh Uniyal
【问题讨论】:
标准更新批处理...
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 数组或部分正整数数组。
【讨论】:
请注意,自 Oracle 12c 以来,情况不应再如此:
对于准备好的语句批处理,该数组包含实际更新计数,指示受每个操作影响的行数。
见https://docs.oracle.com/database/121/JJDBC/oraperf.htm#JJDBC28773
【讨论】:
值 -2 表示元素已成功处理,但受影响的行数未知。
【讨论】:
jdbc-spec 对批量更新的返回码有以下说法:
■ 0 或更大 — 命令已成功处理且值为 更新计数,指示数据库中受到影响的行数 命令的执行 第14章批量更新121
■ Statement.SUCCESS_NO_INFO — 命令已成功处理, 但受影响的行数未知
Statement.SUCCESS_NO_INFO 被定义为 -2,因此您的结果表明一切正常,但您不会获得有关更新列数的信息。
oracle 文档指出:
• 对于准备好的语句批处理,不可能知道批处理中每个单独语句在数据库中影响的行数。因此,所有数组元素的值为 -2。根据 JDBC 2.0 规范,值为 -2 表示操作成功,但受影响的行数未知。
• 对于通用语句批处理,该数组包含指示受每个操作影响的行数的实际更新计数。只有在标准批处理的 Oracle 实现中的通用语句的情况下,才能提供实际的更新计数。
• 对于可调用语句批处理,服务器始终返回值 1 作为更新计数,而与每个操作影响的行数无关。
因此,如果您需要更新计数,您似乎不能使用PreparedStatements,但必须回退到普通的Statements。
【讨论】: