我有一个存储过程,如下所示:
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')已经在表中,是否会插入其他不存在的行(上面的情况为第二行和第三行)?或者根本不会插入任何一个?
我担心它们都不会插入(我的测试用例部分证实了这一点)......如果是这样,我有什么选择来实现所需的行为?有没有一种很好的方法可以使用上面的结构插入不违反主键的行?
答案 0 :(得分: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)
)
另一种选择是使用error logging
INSERT INTO result_table
SELECT ... FROM query_table
LOG ERRORS INTO err$_dest ('INSERT') REJECT LIMIT UNLIMITED;
注意:您必须在运行此查询之前创建错误表。
答案 1 :(得分:2)
您可以使用MERGE
声明。如果记录不存在则插入记录,如果记录已存在则不执行任何操作。
答案 2 :(得分: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