Oracle 'INSERT ALL' 忽略重复项

标签 oracle insert duplicates unique-constraint

我有一个带有唯一约束的数据库表(唯一 (DADSNBR, DAROLEID) 对)。我将同时向这个表中插入多个值,所以我想使用一个查询来完成它 - 我假设这将是更快的方法。我的查询是这样的:

INSERT ALL
    INTO ACCESS (DADSNBR, DAROLEID) VALUES (68, 1)
    INTO ACCESS (DADSNBR, DAROLEID) VALUES (68, 2)
    INTO ACCESS (DADSNBR, DAROLEID) VALUES (68, 3)
    INTO ACCESS (DADSNBR, DAROLEID) VALUES (68, 4)
SELECT 1 FROM DUAL

由于语句中的某些条目与数据库中已有的条目重复,因此整个插入失败并且没有插入任何行。

有没有办法忽略唯一约束失败的情况,只需插入唯一约束,而不必将其拆分为单独的 INSERT 语句?

编辑:我意识到无论如何我可能不想这样做,但我仍然很好奇这是否可能。

最佳答案

在 Oracle 中,语句要么完全成功,要么完全失败(它们是原子的)。但是,您可以在某些情况下添加子句来记录异常而不是引发错误:

  • 使用 BULK COLLECT - SAVE EXCEPTIONS ,如 this thread on askTom 中所示,
  • 或使用 DBMS_ERRLOG (我认为从 10g 开始可用)。

  • 第二种方法是全自动的,这是一个演示(使用 11gR2):
    SQL> CREATE TABLE test (pk1 NUMBER,
      2                     pk2 NUMBER,
      3                     CONSTRAINT pk_test PRIMARY KEY (pk1, pk2));
    
    Table created.
    
    SQL> /* Statement fails because of duplicate */
    SQL> INSERT into test (SELECT 1, 1 FROM dual CONNECT BY LEVEL <= 2);
    
    ERROR at line 1:
    ORA-00001: unique constraint (VNZ.PK_TEST) violated
    
    SQL> BEGIN dbms_errlog.create_error_log('TEST'); END;
      2  /
    
    PL/SQL procedure successfully completed.
    
    SQL> /* Statement succeeds and the error will be logged */
    SQL> INSERT into test (SELECT 1, 1 FROM dual CONNECT BY LEVEL <= 2)
      2   LOG ERRORS REJECT LIMIT UNLIMITED;
    
    1 row(s) inserted.
    
    SQL> select ORA_ERR_MESG$, pk1, pk2 from err$_test;
    
    ORA_ERR_MESG$                                       PK1 PK2
    --------------------------------------------------- --- ---
    ORA-00001: unique constraint (VNZ.PK_TEST) violated   1   1
    

    您可以使用 LOG ERROR条款与 INSERT ALL (感谢 @Alex Poole ),但您必须在每个表后添加子句:
    SQL> INSERT ALL
      2   INTO test VALUES (1, 1) LOG ERRORS REJECT LIMIT UNLIMITED
      3   INTO test VALUES (1, 1) LOG ERRORS REJECT LIMIT UNLIMITED
      4  (SELECT * FROM dual);
    
    0 row(s) inserted.
    

    关于Oracle 'INSERT ALL' 忽略重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13420461/

    相关文章:

    oracle - TNS-12505 : TNS:listener does not currently know of SID given in connect descriptor

    tsql - 如果行不存在,则sql条件插入

    sql - 在 Oracle 中将字符串日期转换为日期时间

    c# - C# Dapper 中的 dbms_output.Put_line

    oracle - 从 PL/SQL 中的过程返回值的数组

    java - Android 批量插入或忽略 JSONArray

    sql - 是否有一个网站可以粘贴 SQL 插入语句并让它按列分解?

    mysql - 如何在两个或多个连接表中获得重复结果?

    python - 如何加入数据框中共享相同名称的列

    excel - 在excel中为重复项添加后缀