当前位置: 首页 > 知识库问答 >
问题:

Java jdbc只批量插入新行

强才捷
2023-03-14

如何仅对新行(目标表中不存在ID列值)使用jdbc有效地执行对Sql Server表的批处理插入?

实际上,我使用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);

}

共有2个答案

晏富
2023-03-14

我还发现了使用merge的另一种可能的解决方案:

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, ?, ?)";
易焱
2023-03-14

一个选项是在表中决定唯一性的三列上添加唯一约束。然后,尝试插入重复记录会导致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);
 类似资料:
  • 我正在写一个数据挖掘程序,可以批量插入用户数据。 当前SQL只是一个普通的批量插入: 如果发生冲突,如何进行更新?我试过: 但它抛出

  • 问题内容: 有没有办法像在MySQL服务器上那样批量执行查询? 将无法使用,因为如果该字段已经存在,它将直接忽略该字段并且不插入任何内容。 将无法工作,因为如果该字段已经存在,它将首先对其进行处理,然后再次进行处理,而不是对其进行更新。 可以使用,但不能批量使用。 因此,我想知道是否可以批量发出这样的命令(一次不止一次发送)。 问题答案: 您 可以 使用INSERT … ON DUPLICATE

  • 问题内容: 我不确定是否在批量索引编制中正确使用了该操作。 我的要求是: 网址是: 我想我错过了文档中的某些内容,但仍然找不到如何进行此操作的方法。 我想要 在索引中创建以上文档,或者如果存在则对其进行更新。 问题答案: 如果您通过批量API将索引中的记录添加为 那么如果该ID已经存在于索引中,您将获得一个异常。如果要添加或 替换 文档(取决于文档是否存在),则应按以下方式进行请求 如果已经存在具

  • 问题内容: 这是我在阅读有关jpa批量插入的几个主题之后创建的简单示例,我有2个持久对象User和Site。一个用户可以拥有多个站点,因此我们在这里有一对多的关系。假设我要创建用户并将多个站点创建/链接到用户帐户。考虑到我愿意为Site对象使用批量插入,代码如下所示。 但是,当我运行此代码时(我将hibernate方式用作jpa实现提供程序),我看到以下sql输出: 所以,我的意思是“真实的”批量

  • 问题内容: 我需要从每日CSV文件中消耗大量数据。CSV包含约12万条记录。使用hibernate模式时,这会减慢爬行速度。基本上,当使用saveOrUpdate()时,hibernate似乎在每个单独的INSERT(或UPDATE)之前执行SELECT。对于使用saveOrUpdate()持久存储的每个实例,在实际的INSERT或UPDATE之前发出SELECT。我能理解为什么要这样做,但是在进

  • 问题内容: 我正在寻找一种对重复键Update(例如SQL Server 2005中的操作)执行插入的解决方案。此操作可能会插入或更新大量条目。SQL Server 2008有一个整洁的操作MERGE,可以很好地完成它,问题是我们只能使用SQL Server2005。 我研究了标准的解决方案,但是它们都不是很好,因为它们假定只有一个入口已更新/插入。 有谁知道在旧版SQL Server中复制MER