【问题标题】:Batch insert into multiple table with sequence按顺序批量插入多个表
【发布时间】:2019-07-09 08:22:58
【问题描述】:

在我们的 Java 应用程序中实现批量插入代码时遇到了一个问题。下面是我们的表结构-

  • 我们有三个表:Table1、Table2 和 Table3。
  • Table1 的主键(SeqId,本质上是序列)是其余两个表(Table2 和 Table3)的外键。

当前实施:

作为当前批处理操作的一部分,对于每次迭代,我们首先在 Table1 中按顺序插入,然后是 Table2 和 Table3。

[伪代码]

INSERT INTO Table1(SeqId, OtherField1) VALUES (ID_SEQ.nextval, 'Some Val');
INSERT INTO Table2(SeqId, OtherField1) VALUES (someId2, ID_SEQ.currval, 'Some Val');
INSERT INTO Table3(SeqId, OtherField1) VALUES (someId3, ID_SEQ.currval, 'Some Val');

我们正在尝试什么:

现在我们正在尝试实现批量插入。我们创建了三个单独的 PreparedStatement,对于每次迭代,我们都在执行statement.addBatch();,最后我们依次执行statement.executeBatch()

现在的问题是ID_SEQ.currval 将始终采用当前序列值,这不是我们想要的。针对 Table1 中 SeqId 的每个值,我们想要 Table2 和 Table3 中的对应行。

是否可以使用批量插入(不是过程或匿名块)来实现这一点?

我们正在使用 Oracle 11gJava8

【问题讨论】:

    标签: java oracle11g batch-insert


    【解决方案1】:

    我认为你可以使用一个变量来存储序列值

    DECLARE
       ID_SEQ PLS_INTEGER;
    BEGIN
       ID_SEQ  := ID_SEQ.nextval;
       INSERT INTO Table1(SeqId, OtherField1) VALUES (ID_SEQ  , 'Some Val');
       INSERT INTO Table2(SeqId, OtherField1) VALUES (someId2, ID_SEQ  , 'Some Val');
       INSERT INTO Table3(SeqId, OtherField1) VALUES (someId3, ID_SEQ  , 'Some Val');
    END;
    

    【讨论】:

    • 我需要一个java解决方案,匿名块我知道怎么做。
    • @Kartic 你能从 Java 调用匿名块而不是使用单独的 SQL 语句吗?
    【解决方案2】:

    您可以检索序列的下一个值并使用该值填充您的表。

    int seq_val = 0;
    ResultSet rs = stmt.execute("SELECT ID_SEQ.NEXTVAL FROM DUAL");
    if ( rs.next() ) {
      seq_val = rs.getInt(1);
    }
    
    Statement statement = connection.createStatement();
    statement.addBatch("INSERT INTO Table1(SeqId, OtherField1)" + "VALUES ("+seq_val+",'some_val')");
    
    statement.addBatch("INSERT INTO Table2(ID,SeqId, OtherField1) " + "VALUES ('some_id',"+seq_val+",'some val')");
    
    statement.addBatch("INSERT INTO Table3(ID,SeqId, OtherField1) " + "VALUES ('some_id',"+seq_val+",'some val')");
    
    statement.executeBatch();
    

    //请原谅任何语法错误,因为我没有使用任何代码编辑器进行验证。 干杯

    【讨论】:

    • 我想到了这一点,但这并没有比我们当前的实现有很大的改进,因为每次迭代我们都必须触发一个 select 语句。有人可以验证这是否是唯一的方法。
    • 你能分享一下你谈到的foreach语句吗,也许这会给我一些见解
    • 循环用于获取 OtherField 值。没有其他逻辑。我不知道,但是如果有任何方法可以将多个语句分组并作为单个单元执行,那就可以了。不确定这是否可行。
    • @Kartic 你决定什么答案对你有用吗?或者你使用了不同的方法,请告诉我们。
    • 我会坚持当前的实现,因为我觉得我的实际问题没有真正的解决方案。
    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2019-07-23
    • 2019-05-16
    相关资源
    最近更新 更多