2015-11-26 174 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