我正在尝试维护数据完整性并将错误记录到错误表中。我有3个具有唯一约束的表和1个错误表:
create table tbl_one (
pass_no number,
constraint tbl_one_u01 unique (pass_no) );
insert into tbl_one values(10);
insert into tbl_one values(20);
create table tbl_two (
cus_no number,
cus_name varchar2(50),
pass_no number,
constraint tbl_two_u01 unique (cus_no) );
insert into tbl_two values( 101, 'NameX',10);
insert into tbl_two values( 102, 'NameY',10);
insert into tbl_two values( 103, 'NameZ',20);
create table tbl_target (
cus_no number,
pass_no number,
constraint tbl_target_u01 unique (cus_no),
constraint tbl_target_u02 unique (pass_no));
exec dbms_errlog.create_error_log('tbl_target','tbl_target_err');
我正在尝试将所有ORA-00001错误记录到错误表tbl_target_err
,如下所示:
begin
insert into tbl_target
select a.pass_no, b.cus_no
from tbl_one a
inner join tbl_two b on b.pass_no = a.pass_no
log errors into tbl_target_err reject limit 10;
end;
结果是:
select * from tbl_target;
-------------------
CUS_NO PASS_NO
101 10
103 20
和错误表:
CUS_NO PASS_NO
102 10
我需要将所有违规错误放入错误表中。如果违反了pass_no 10 的值,则所有 10 值都应插入错误表中;不,一个进入目标,一个进入错误表。我不想使用exists语句,因为我无法记录所有违反的值。
我怎么能这样做?
答案 0 :(得分:1)
您无法使用错误日志记录机制,因为它不是为支持它而设计的。它在尝试在表中创建副本时出错 - 它试图为pass_no
10插入的第一个值本身是有效的 - 因此它必须区分已存在的数据和即将出现的多个值从插入开始。因此,您需要自己动手。
一个选项是创建自己的表来保存重复项,并使用insert all
来确定每个表中属于哪些值:
create table tbl_target_dup (
cus_no number,
pass_no number
);
insert all
when cus_count = 1 and pass_count = 1 then
into tbl_target values (cus_no, pass_no)
else
into tbl_target_dup values (cus_no, pass_no)
select a.pass_no, b.cus_no,
count(*) over (partition by a.pass_no) as pass_count,
count(*) over (partition by b.cus_no) as cus_count
from tbl_one a
join tbl_two b on b.pass_no = a.pass_no;
这允许您拥有比受PK / UK影响的列更多的列,并且如果您愿意,只将它们插入到真实表格中,或者将其插入到“错误”中。表。您只需在每个表格中获得这两列:
select * from tbl_target;
CUS_NO PASS_NO
---------- ----------
103 20
select * from tbl_target_dup;
CUS_NO PASS_NO
---------- ----------
101 10
102 10
你可以使用基于相同select
的两个插入执行相同的操作,一个子查询检查两个计数是1,其他检查至少一个不是,但这可能表现更好。