忽略插入到选择重复键错误(pl / sql)

时间:2017-06-15 05:59:48

标签: sql oracle sql-insert

我想知道在重复键错误之后是否有任何方法可以继续插入select。含义:我想忽略该异常并继续插入下一条记录。 我熟悉ignore_row_on_dupkey_index,但据我所知,不应在生产环境中使用提示。

很少的事情: 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;

3 个答案:

答案 0 :(得分:5)

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

您提到的限制通常涉及与性能调整有关的提示 - 这些提示被认为是最后的选择。

我不认为这是特定提示的情况。 (请参阅herehere

但是,使用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);

此SO post中描述了 LOG ERRORS REJECT LIMIT UNLIMITED的另一种方法。

答案 1 :(得分:1)

  

我知道,不应该在生产环境中使用提示。

对于性能调优提示,这是可取的。但是ignore_row_on_dupkey_index()与其他提示不同,它具有语义效果,它实际上改变了查询的行为方式。因此,如果它是一个临时查询,或者您从OLTP中提取数据并将其加载到DWH数据库中,我个人认为使用它没有任何问题。 但首选的方法是使用insert语句的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 

答案 2 :(得分:0)

我认为您应该使用批量收集以获得高性能,并在构建的异常中使用。

请浏览链接:http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html并查看更多符合您要求的示例。

根据我的经验,与逐个插入相比,它的速度提高了10倍或更快。