是否可以确定哪些行受SQL Server UPDATE影响?

时间:2018-10-04 03:15:53

标签: java sql sql-server

我正在使用Java程序更新SQL Server 2017数据库。目前,在测试我的import React from "react"; import ReactDOM from "react-dom"; import { hashHistory, Router, Route, Link } from "react-router"; // components import Home from "./components/Home"; import About from "./components/About"; const App = ({children}) => ( <div>{children}</div> ) const routes = { path: "/", component: App, indexRoute: { component: Home }, childRoutes: [{ path: "about", component: About }] }; const root = document.getElementById("root"); ReactDOM.render(<Router history={hashHistory} routes={routes} />, document.body) 语句时,我没有提交更改(UPDATE)。

当我打印出受影响的行数时,计数大大低于预期(UPDATE语句应在每一行进行更新)。

下面是一些示例代码,这些代码演示了我用来发出connection.setAutoCommit(false)语句的循环:

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而不是我期望的32,000。

有没有办法返回受影响的行?我想将匹配项与不匹配项进行比较。

我已经尝试使用相同的33 rows affected条件将循环修改为SELECT语句,并返回所有32,000条记录,因此我确信这些记录确实存在。 em>

1 个答案:

答案 0 :(得分:1)

您将在循环的每次迭代中创建一个新的PreparedStatement。您需要在调用executeBatch的同一prepareStatement对象上排队批处理执行。当前,您只执行第1000个排队的查询。

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=?");

preparedStatement = connection.prepareStatement(sql.toString());

for (User user : updatedUsers) {
        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();
        }
}

要确定受影响的行(在SQL Server 2005+中),可以在SQL中使用OUTPUT子句,以使数据库返回受影响的行数据。 Article