【问题标题】:Insert multiple rows in a oracle database from java using getGeneratedKeys() in one statement在一个语句中使用 getGeneratedKeys() 从 java 在 oracle 数据库中插入多行
【发布时间】:2019-04-23 08:24:36
【问题描述】:

我已经了解了 INSERT ALL 语法,只要我不想检索插入的 id 值,它就可以正常工作。

与 INSERT ALL 语法相反,我可以在一个事务中使用多个 INSERT INTO 语句,这会起作用但对性能不利,如下所述:Best way to do multi-row insert in Oracle?

这是我当前的代码:

//Creation of INSERT INTO statement
//...    
Statement statement = dbConnection.createStatement();
statement.executeUpdate(INSERT_SQL, new String[] {"someIDColumn"});
ResultSet idResulSet = statement.getGeneratedKeys();
//Usage of the generated keys

它适用于单行,但如果我尝试 INSERT ALL 语法,我会得到:

java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束

原因:错误:933,位置:187,Sql = INSERT ALL INTO bpos(artnr, bstnr, menge) VALUES (3, 31, 4) INTO bpos(artnr, bstnr, menge) VALUES (5, 31, 6) INTO bpos(artnr, bstnr, menge) VALUES (1, 31, 2) SELECT * FROM dual RETURNING artnr INTO :1 , OriginalSql = INSERT ALL INTO bpos(artnr, bstnr, menge) VALUES (3, 31, 4) INTO bpos(artnr, bstnr, menge) 值 (5, 31, 6) INTO bpos(artnr, bstnr, menge) 值 (1, 31, 2) SELECT * FROM dual RETURNING artnr INTO ?, Error Msg = ORA-00933: SQL 命令未正确结束

是否可以在 INSERT ALL 语句之后检索所有插入的 id?

【问题讨论】:

  • 您是否尝试过使用批处理执行?我不确定 Oracle 驱动程序是否支持批量执行生成的密钥检索(鉴于 JDBC 将其定义为可选/特定于实现),但它可能比生成自己的查询字符串更好。

标签: java sql oracle jdbc ojdbc


【解决方案1】:

使用:

statement.executeBatch

不是:

statement.executeUpdate

【讨论】:

    【解决方案2】:

    嗯,据我所知,这是可能的,但不是直接的(因为您可以通过更新或删除来做到这一点);必须使用一点解决方法

    这是一个例子:

    SQL> create table test (id number, name varchar2(20));
    
    Table created.
    
    SQL> declare
      2    type    tt_test is table of test%rowtype index by binary_integer;
      3    l_test  tt_test;
      4    l_id    sys.odcinumberlist;
      5  begin
      6    select id, name
      7      bulk collect into l_test
      8      from (select 111 id, 'Little' name from dual union all
      9            select 222 id, 'Foot'   name from dual
     10           );
     11
     12    forall i in l_test.first .. l_test.last
     13      insert into test (id, name) values (l_test(i).id, l_test(i).name)
     14      returning l_test(i).id bulk collect into l_id;
     15
     16    for i in l_id.first .. l_id.last loop
     17      dbms_output.put_line('Inserted ID = ' || l_id(i));
     18    end loop;
     19  end;
     20  /
    Inserted ID = 111
    Inserted ID = 222
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    不过,我不知道,您能否在您的(Java?)代码中使用它,因为我不会说那种语言。

    【讨论】:

    • 这可能有效,但您使用了 INSERT INTO 语法,这意味着我必须对我想要插入的每一行进行插入。我正在寻找的是主要出于性能原因使用 INSERT ALL INTO ... 语句(或类似的语句)。我可以想象它无法完成,因为 INSERT ALL INTO 可以将值插入到不同的表中。
    • 您的 INSERT ALL 被 BULK COLLECT 和 FORALL 的组合替换(我的代码中的第一条和第二条语句)。正如我所说,我认为 INSERT ALL 本身不能与 RETURNING INTO 子句一起使用。
    猜你喜欢
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    相关资源
    最近更新 更多