【问题标题】:Java jdbc batch insert only new rowsJava jdbc 批量只插入新行
【发布时间】:2019-01-17 11:25:50
【问题描述】:

我怎样才能有效地使用 jdbc 对 Sql Server 表执行批量插入,仅用于新行(目标表中不存在 ID 列值)?

实际上我使用PreparedStatement 对象来创建批次,但没有“仅在新行时插入”逻辑:

String sqlInsertStub = "INSERT INTO mytable (id, col2, col3) values (?, ?, ?)";

try (PreparedStatement preparedStatement = connection.prepareStatement(sqlInsertStub)) {

    connection.setAutoCommit(false);

    int processed = 0;

    while (resultSet.next()) {

        // [...]

        preparedStatement.setInt(1, id);
        preparedStatement.setString(2, col2);
        preparedStatement.setString(3, col3);

        preparedStatement.addBatch();

        if (++processed % BATCH_SIZE == 0) {
            preparedStatement.executeBatch();
            connection.commit();
        }

    }

    preparedStatement.executeBatch();
    connection.commit();    


catch (Exception e) {

    connection.rollBack();
    e.printStackTrace();
    System.exit(1);

}

【问题讨论】:

    标签: java sql-server jdbc batch-insert


    【解决方案1】:

    一种选择是在表中确定唯一性的三列上添加唯一约束。然后,尝试插入重复记录会导致 Java 异常。但是,这可能会导致整个批次失败。如果您需要其他选项,可以将查询更改为以下内容:

    INSERT INTO mytable
    SELECT ?, ?, ?
    WHERE NOT EXISTS (SELECT 1 FROM mytable
                      WHERE id = ? AND col2 = ? AND col3 = ?);
    

    对于此查询,您将值绑定两次,如下所示:

    preparedStatement.setInt(1, id);
    preparedStatement.setString(2, col2);
    preparedStatement.setString(3, col3);
    preparedStatement.setInt(4, id);
    preparedStatement.setString(5, col2);
    preparedStatement.setString(6, col3);
    

    【讨论】:

    • 还可以使用anonymous code block 来避免必须两次传递参数值。
    • @GordThompson 行值构造函数可能更简单。
    【解决方案2】:

    我还使用合并找到了其他可能的解决方案:

    String sqlInsertStub = "MERGE INTO mytable a USING (SELECT ? ID) b " +
                            "ON (a.ID = b.ID)" +
                            "WHEN NOT MATCHED " +
                            "THEN INSERT (ID, COL1, COL2) VALUES(b.ID, ?, ?)";
    

    【讨论】:

      猜你喜欢
      • 2011-01-14
      • 2011-02-28
      • 1970-01-01
      • 2019-06-24
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多