如何跳过唯一约束错误

时间:2015-11-26 21:14:44

标签: sql oracle

我正在尝试将值插入到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

3 个答案:

答案 0 :(得分:7)

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

HUSQVIK@hq_pdb_tcp> CREATE TABLE tmp (val NUMBER CONSTRAINT pk_tmp PRIMARY KEY);

Table created.

HUSQVIK@hq_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,只创建了一行。

答案 1 :(得分: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);

然后在你的insert语句中用一个log errors子句结束它:

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

您可以选择接受固定数字的拒绝限制,允许您在引发实际错误之前指定对错误的容差,而不是仅允许将行放在错误表中。

答案 2 :(得分: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