2015-11-26 154 views
0

我试图将值插入SQL表,但我在SQL查询如何跳过唯一约束错误

SQL Error: ORA-00001: unique constraint (uniqueKey) violated 
00001. 00000 - "unique constraint (%s.%s) violated" 
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key. 
     For Trusted Oracle configured in DBMS MAC mode, you may see 
     this message if a duplicate entry exists at a different level. 
*Action: Either remove the unique restriction or do not insert the key. 

收到此错误有没有跳过此错误并继续插入的方式。这样

try 
    insert query 
catch (unique constraint error) 
    continue inserting other values 
+0

这可能是[此问题](http://stackoverflow.com/q/9332360/409172)的副本。 –

回答

5

存在提示ignore_row_on_dupkey_index(<table name>, <unique index name>)

[email protected]_pdb_tcp> CREATE TABLE tmp (val NUMBER CONSTRAINT pk_tmp PRIMARY KEY); 

Table created. 

[email protected]_pdb_tcp> INSERT /*+ ignore_row_on_dupkey_index(tmp, pk_tmp) */ INTO tmp (val) SELECT 1 FROM DUAL CONNECT BY LEVEL <= 3; 

1 row created. 

请参阅我插入三个值1,只创建一行。

+0

只有提示我会有a)它的沉默,并没有记录错误,b)它的11gr2向前具体,我们没有在OP的版本信息。它确实工作。 – Andrew

+1

它总是取决于实际使用情况,为什么存在多个选项。这只是另一个应该提及的选项。 – Husqvik

+0

关于提示的文章http://guyharrison.squarespace.com/blog/2010/1/1/the-11gr2-ignore_row_on_dupkey_index-hint.html – are

0

东西有一个LOG ERRORS条款,允许您登录,在一个错误的表会导致错误的行 - 使用DBMS包创建此错误表:

DBMS_ERRLOG.CREATE_ERROR_LOG(table_being_inserted_into ,name_of_table_for_errors ,NULL,NULL,TRUE); 

https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_errlog.htm

函数签名:

DBMS_ERRLOG.CREATE_ERROR_LOG (
    dml_table_name   IN VARCHAR2, 
    err_log_table_name  IN VARCHAR2 := NULL, 
    err_log_table_owner  IN VARCHAR2 := NULL, 
    err_log_table_space  IN VARCHAR2 := NULL, 
    skip_unsupported   IN BOOLEAN := FALSE); 

然后在你插入语句,你有一个日志错误条款结束吧:

LOG ERRORS INTO your_error_table_name ('description of your choosing') REJECT LIMIT UNLIMITED; 

您可以选择接受拒绝固定数量的限制,让您在效果指定的容错性,它抛出一个真正的前错误,而不是只允许行放置在错误表中。

0

简单的示例是插入for loop,而忽略例外:

begin 
    for rc in (select * from <your query> loop 
    begin 
    insert into t1(...) values (...); 
    exceptions when others then 
    null;--ignore any exceptions do nothing 
    end; 
    end loop; 
end 

其他样品 - 同样的想法,但使用FORALL批量操作和SAVE EXCEPTIONS

declare 
    cursor C is 
    select ID, OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, 
      decode(mod(rownum,100000), 1, rpad('*',20,'*'), OBJECT_TYPE) object_type, 
      CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS, TEMPORARY, GENERATED, SECONDARY 
     from big_table; 
    type array is table of c%rowtype; 
    l_data array; 

    dml_errors EXCEPTION; 
    PRAGMA exception_init(dml_errors, -24381); 
    l_errors number; 
    l_errno number; 
    l_msg varchar2(4000); 
    l_idx number; 
begin 
    open c; 
    loop 
     fetch c bulk collect into l_data limit 100; 
     begin 
      forall i in 1 .. l_data.count SAVE EXCEPTIONS 
       insert into t2 values l_data(i); 
     exception 
      when DML_ERRORS then 
       l_errors := sql%bulk_exceptions.count; 
       for i in 1 .. l_errors 
       loop 
        l_errno := sql%bulk_exceptions(i).error_code; 
        --do smth with the exceptions 
       end loop; 
     end; 
     exit when c%notfound; 
    end loop; 
    close c; 
end; 

的更多信息可见AskTom和OraMagazine

https://asktom.oracle.com/pls/asktom/f?p=100:11:0%3A%3A%3A%3AP11_QUESTION_ID:1422998100346727312

http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html