【发布时间】:2018-10-04 03:15:52
【问题描述】:
我正在使用 Java 程序更新 SQL Server 2017 数据库。目前,在测试我的 UPDATE 语句时,我没有提交更改 (connection.setAutoCommit(false))。
当我打印出受影响的行数时,计数远低于预期(UPDATE 语句应该更新每一行)。
这里是一些示例代码,演示了我用来发出UPDATE 语句的循环:
// List of users that need to be updated
List<User> updatedUsers = new ArrayList<>();
// Connect to database
Connection connection = null;
connection = DataFiles.getServerConnection();
connection.setAutoCommit(false);
PreparedStatement preparedStatement = null;
int rowsAffected = 0;
final int batchSize = 1000;
int count = 0;
// Create an UPDATE statement for each record to be updated
for (User user : updatedUsers) {
StringBuilder sql = new StringBuilder(
"UPDATE USERS SET\n"
);
sql.append("USER_TYPE=?,\n")
.append("FIRST_NAME=?,\n")
.append("LAST_NAME=?,\n")
.append("EMAIL_ADDRESS=?\n");
sql.append("WHERE USER_ID=?");
// Fill each ?
preparedStatement = connection.prepareStatement(sql.toString());
preparedStatement.setString(1, user.getUserTypeId());
preparedStatement.setString(2, user.getFirstName());
preparedStatement.setString(3, user.getLastName());
preparedStatement.setString(4, user.getEmailAddress());
preparedStatement.setString(5, user.getUserId());
preparedStatement.addBatch();
// Submit in batches of 1000
if (++count % batchSize == 0) {
rowsAffected += IntStream.of(preparedStatement.executeBatch()).sum();
preparedStatement.clearBatch();
}
}
System.out.println(count);
rowsAffected += IntStream.of(preparedStatement.executeBatch()).sum();
preparedStatement.clearBatch();
preparedStatement.close();
System.out.println(rowsAffected + " rows affected!");
我的 WHERE 语句应该与循环的每次传递都匹配一条记录,但我得到的是 33 rows affected 而不是我期望的 32,000。
有没有办法返回受影响的行?我想将匹配项与不匹配项进行比较。
我已经尝试将我的循环调整为具有相同 WHERE 标准的 SELECT 语句并返回所有 32,000 条记录,所以我确信这些记录确实存在。 p>
【问题讨论】:
-
@Nick - 有可能,但不太可能。实际上,我不希望所有 32,000 行都更新,但比 33 多得多。但这就是为什么我想知道哪些行受到影响,以便找出原因。
-
这是一个生产数据库,所以我想在提交更新之前说服自己它是准确的。
-
您是否知道在代码的最后只打印一次
rowsAffected?您如何检查每批后的更新计数? -
@TimBiegeleisen - 是的,但我会在每次批量更新时添加到
rowsAffected。所以我在打印时的假设是,这将反映每批受影响的所有行。 -
@TimBiegeleisen 今天我学到了一些新东西。
标签: java sql sql-server