【问题标题】:ExecuteBatch method return array of value -2 in javajava中的ExecuteBatch方法返回值-2的数组
【发布时间】:2013-10-02 01:31:40
【问题描述】:

当我在java中执行executeBatch方法时,它返回一个很好的int数组,但所有数组元素的值为-2,

它应该是 0 或 +ve 数字,表示受影响的行数, 但它返回 -2,

当我在数据库中检查它时,所有更新都成功完成。 请解释这个 -2 的含义以及我如何找到受影响的行数。

谢谢, Deepesh Uniyal

【问题讨论】:

  • 写下你试过的代码......

标签: java oracle jdbc


【解决方案1】:

标准更新批处理...

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 数组或部分正整数数组。

【讨论】:

    【解决方案2】:

    请注意,自 Oracle 12c 以来,情况不应再如此:

    对于准备好的语句批处理,该数组包含实际更新计数,指示受每个操作影响的行数。

    https://docs.oracle.com/database/121/JJDBC/oraperf.htm#JJDBC28773

    【讨论】:

      【解决方案3】:

      值 -2 表示元素已成功处理,但受影响的行数未知。

      specs

      【讨论】:

      • 是获取受影响行数的任何方法。 ??请建议。
      【解决方案4】:

      jdbc-spec 对批量更新的返回码有以下说法:

      ■ 0 或更大 — 命令已成功处理且值为 更新计数,指示数据库中受到影响的行数 命令的执行 第14章批量更新121

      ■ Statement.SUCCESS_NO_INFO — 命令已成功处理, 但受影响的行数未知

      Statement.SUCCESS_NO_INFO 被定义为 -2,因此您的结果表明一切正常,但您不会获得有关更新列数的信息。

      oracle 文档指出:

      • 对于准备好的语句批处理,不可能知道批处理中每个单独语句在数据库中影响的行数。因此,所有数组元素的值为 -2。根据 JDBC 2.0 规范,值为 -2 表示操作成功,但受影响的行数未知。

      • 对于通用语句批处理,该数组包含指示受每个操作影响的行数的实际更新计数。只有在标准批处理的 Oracle 实现中的通用语句的情况下,才能提供实际的更新计数。

      • 对于可调用语句批处理,服务器始终返回值 1 作为更新计数,而与每个操作影响的行数无关。

      因此,如果您需要更新计数,您似乎不能使用PreparedStatements,但必须回退到普通的Statements。

      【讨论】:

      • 感谢 piet.t,但是我怎样才能获得批量受影响的行数,根据我的流程,我们必须知道它,我们正在更新数据库中的 600 tps,所以我不能避免批处理,请建议。
      • 添加了一些预言机信息。我不知道这是否会有所帮助,但你可以试试。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-21
      • 1970-01-01
      • 2021-05-10
      • 2012-12-18
      • 1970-01-01
      • 2015-12-07
      • 2011-02-19
      相关资源
      最近更新 更多