2017-06-15 133 views
1

我想知道是否有任何方法在重複鍵錯誤後繼續插入select。意思是:我想忽視例外並繼續插入下一條記錄。 我很熟悉ignore_row_on_dupkey_index,但據我所知,提示不應該在生產環境中使用。忽略插入到選擇重複鍵錯誤(pl/sql)

幾件事: 1.查詢將數百萬條記錄插入空表中。 2.我寧願有一個很好的解決方案,對性能影響很小。

謝謝, 亞歷克斯

使用ignore_row_on_dupkey_index的代碼示例:

CREATE TABLE customers 
(customer_id number(10) NOT NULL, 
    customer_name varchar2(50) NOT NULL, 
    city varchar2(50), 
    CONSTRAINT customers_pk PRIMARY KEY (customer_id) 
); 


CREATE TABLE customers_2 
(customer_id number(10) NOT NULL, 
    customer_name varchar2(50) NOT NULL, 
    city varchar2(50) 

); 

insert into customers_2 values(1,'A','TLV'); 
insert into customers_2 values(2,'B','TLV'); 
insert into customers_2 values(2,'C','TLV'); 
insert into customers_2 values(3,'C','TLV'); 


SELECT * FROM customers_2 

insert /*+ ignore_row_on_dupkey_index(customers, customers_pk) */ 
into customers select * from customers_2 

select * from Customers; 
+0

它在proc中工作。我不能得到什麼問題 –

+0

根據ORACLE提示有問題和已知的錯誤,因此它不應該在生產中使用,這就是爲什麼我正在尋找一個類似的解決方案。 –

回答

0

我知道,提示是不應該在生產環境中使用。

對於性能調整提示,建議這樣做。但ignore_row_on_dupkey_index()不像其他提示,它具有語義效果,它實際上改變了查詢的行爲方式。因此,如果是即席查詢,或者您從OLTP中提取數據並將其加載到DWH數據庫中,我個人認爲使用它沒有任何問題。 但首選的方法是使用插入語句的log errors子句,它允許您實際記錄「錯誤」行,以便您稍後可以期待它們。這裏是一個例子:

create table t1(
    c1 number constraint t1_pk primary key 
); 

-- create errors logging table 
exec dbms_errlog.create_error_log(dml_table_name=>'T1'); 

-- our query 
insert into t1 
    select 1 
    from dual 
    connect by level <= 3 
    log errors reject limit unlimited; 

    1 row created. 

-- "good rows" 
select * 
    from t1 

     C1 
---------- 
     1 
1 row selected. 

-- "bad rows" 

column ora_err_mesg$ format a30 
column c1 format a10 

select ora_err_mesg$ 
     , c1 
    from err$_t1 

    ORA_ERR_MESG$     C1   
------------------------------ --------- 
ORA-00001: unique constraint (... 1 
ORA-00001: unique constraint (... 1 
3

首先,此特定提示ignore_row_on_dupkey_index不像其他提示。

您提到的限制通常與提示有關的性能調整 - 而這些提示被認爲是最後的手段。

我不認爲這是具體提示的情況。 (見here,和here

然而,相同的結果可能與merge

merge into "customers" a 
using 
( 
    select * from customers_2 
) b 
on (a.customer_id = b.customer_id) 
when not matched then 
    insert (customer_id , customer_name,city) 
    values (b.customer_id , b.customer_name, b.city); 

另外,來實現與另一LOG ERRORS REJECT LIMIT UNLIMITED方法在該SO post進行說明。

+1

如果您只是想讓它與之相伴,MERGE就很好,如果您想知道哪些記錄失敗,那麼LOG ERRORS解決方案就很好。 – BriteSponge