1

我有一个如下所示的存储过程:

BEGIN
  INSERT INTO result_table
  (SELECT (...) FROM query_table);
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    NULL;
END;

我在将多个参数传递给 SELECT 语句的循环中执行此操作,在某些情况下,某些值可能会重复,这就是我必须捕获 DUP_VAL_ON_INDEX 异常的原因。

我的问题是,如果 SELECT 语句返回更多行并且其中只有一个已经存在于 *result_table*, f. 前任。

1 'A'
2 'B'
3 'C'

并且第一行(1'A')已经在表中,是否会插入其他不存在的行(上面的第二个和第三个)?或者根本不会插入它们?

恐怕它们都不会被插入(我的测试用例部分证实了这一点)......如果是这样,我必须有什么选择来实现所需的行为?有没有使用上面的结构插入不违反主键的行的好方法?

4

3 回答 3

2

您可以使用该MERGE语句。如果记录不存在则插入记录,如果记录已存在则不执行任何操作。

http://psoug.org/reference/merge.html

于 2013-02-02T09:54:43.700 回答
2

您是对的,如果一条记录违反约束,则不会插入任何记录。我会做

INSERT INTO result_table
(SELECT (...) FROM query_table a WHERE NOT EXISTS
(SELECT NULL FROM result_table b WHERE b.b_unique_key = a.b_unique_key)
)

另一种选择是使用错误记录

INSERT INTO result_table
SELECT ... FROM query_table 
LOG ERRORS INTO err$_dest ('INSERT') REJECT LIMIT UNLIMITED;

注意:您必须在运行此查询之前创建错误表。

于 2013-02-01T15:38:43.387 回答
0

如果您使用的是 11g,那么您可以使用ignore_row_on_dupkey_index提示来抑制错误:

create table tab (id integer);

alter table tab add constraint tab_pk primary key (id);

insert into tab
  select rownum from dual connect by level <= 1;

1 rows inserted.
        ID
----------
         1 

SELECT * FROM tab;

insert into tab
  select rownum from dual connect by level <= 3;

SQL Error: ORA-00001: unique constraint (CAM_OWNER.TAB_PK) violated

insert /*+ ignore_row_on_dupkey_index(tab, tab_pk) */into tab
  select rownum from dual connect by level <= 3;

SELECT * FROM tab;

2 rows inserted.
        ID
----------
         1 
         2 
         3 
于 2013-02-01T15:43:30.610 回答