受影响的 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()