受影响的 Oracle JDBC batchUpdate 行始终为 -2 (Statement.SUCCESS_NO_INFO)

Posted

技术标签:

【中文标题】受影响的 Oracle JDBC batchUpdate 行始终为 -2 (Statement.SUCCESS_NO_INFO)【英文标题】:Oracle JDBC batchUpdate rows affected is always -2 (Statement.SUCCESS_NO_INFO) 【发布时间】:2015-05-31 12:57:07 【问题描述】:

我有一个执行批量更新语句的批处理。

在使用 Spring JDBC 4.1.6 和 Oracle Jdbc 驱动程序(ojdbc7 和 ucp)实现批处理支持后,单个更新请求(在批处理中)受影响的记录数始终检索为 -2 (Statement.SUCCESS_NO_INFO)。

有什么方法可以知道受单个更新请求影响的行(参数设置为批处理),因为我必须在此之后使用 INSERT 语句重试相同的参数??

在技术上尝试将其开发为 UPSERT 实现

我以三种不同的方式尝试了此批量更新,并且在所有三种方法中,结果都是相同的——(它只是告诉我 Statement.SUCCESS_NO_INFO (-2))

方法一——直接UCP连接和PreparedStatement

    connectionPoolMgr.startConnectionPool("mgr_pool");
    Connection connection = pds.getConnection();

    PreparedStatement pstmt = connection.prepareStatement(dmlSQL);
    pstmt.setInt(1, pkId);
    pstmt.setInt(2, idx * 10);
    pstmt.addBatch();

   // EVERY ELEMENT IN THIS ARRAY IS ALWAYS returned as -2
   int updatedRows[] = pstmt.executeBatch();

方法 2 - Spring JdbcTemplate 和 batchUpdate()

 MapSqlParameterSource[] paramsArray = getSqlParameterList().toArray(new MapSqlParameterSource[0]);

      // EVERY ELEMENT IN THIS ARRAY IS ALWAYS returned as -2
 int[] batchUpdateResult = getNamedParameterJdbcTemplate().batchUpdate(sqlStatement, paramsArray);  

方法 3 - Spring BatchSqlUpdate 实现

   BatchInsert batchInsert = new BatchInsert(dataSource);
   for (int i = 0; i < count; i++) 
        MapSqlParameterSource param = new MapSqlParameterSource();
        param.addValue("ID", i + 100);
        param.addValue("FIRST_NAME", "Name" + i);

        batchInsert.updateByNamedParam(param.getValues());
    

    batchInsert.flush();
    int rowsAffected[] = batchInsert.getRowsAffected();

    class BatchInsert extends BatchSqlUpdate  
          private static final String SQL = "UPDATE t_customer_test SET first_name = :FIRST_NAME)  WHERE id  = :ID";

          BatchInsert(DataSource dataSource) 
              super(dataSource, SQL);
              declareParameter(new SqlParameter(Types.VARCHAR));
              declareParameter(new SqlParameter(Types.INTEGER));
              setBatchSize(100);
              compile();
         
  

【问题讨论】:

在OTN网络上问了同样的问题,得到了一些有用的答案。目前我正在尝试使用 MERGE 语句将其实现为 UPSERT。链接:community.oracle.com/message/12980203 【参考方案1】:

从 12.1 开始,Oracle 数据库返回批次中每个元素的更新行数。您将需要 12.1 数据库和驱动程序 (12.1.0.2)。此功能在早期版本的数据库中不存在。

所以从 12.1 开始:

int updatedRows[] = pstmt.executeBatch();

实际上将返回一个数组,其中包含批处理中每个元素的更新行数,而不是 -2。顺便说一句,此功能仅在 JDBC 瘦驱动程序中。

【讨论】:

以上是关于受影响的 Oracle JDBC batchUpdate 行始终为 -2 (Statement.SUCCESS_NO_INFO)的主要内容,如果未能解决你的问题,请参考以下文章

JdbcBatchItemWriterBuilder 与 org.springframework.jdbc.core.jdbcTemplate.batchUpdate

JDBC连接oracle executeBatch方法执行成功返回值-2

执行 jdbc batchUpdate 时出现 DeadlockLoserDataAccessException

Spring JdbcTemplate.batchUpdate()

受 Microsoft JDBC 驱动程序的 SELECT INTO 查询影响的行数

SSIS 执行 SQL 任务,受 MERGE 语句影响的行(Oracle 和 SQL Server)