2017-06-15 140 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