代码之家  ›  专栏  ›  技术社区  ›  Zephyr

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

  •  0
  • Zephyr  · 技术社区  · 7 年前

    我正在使用Java程序更新SQL Server 2017数据库。目前,在测试我的 UPDATE 声明,我没有提交更改( connection.setAutoCommit(false) ).

    下面是一些示例代码,演示了我用来发布 更新

        // 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

    是否有方法返回受影响的行?我想把匹配的和不匹配的进行比较。

    我已经试着将我的循环适应于 SELECT 哪里 它返回所有32000条记录,所以我确信这些记录确实存在。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Deadron    7 年前

    在循环的每次迭代中都创建一个新的PreparedStatement。您需要对调用executeBatch的同一preparedStatement对象上的批处理执行进行排队。目前您只执行第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();
            }
    }
    

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