データの整合性を維持し、エラーをエラーテーブルに記録しようとしています。一意の制約を持つ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');
次のtbl_target_err
ように、すべてのORA-00001エラーをエラーテーブルに記録しようとしています。
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個の値すべてをエラーテーブルに挿入する必要があります。1つはターゲットに、もう1つはエラーテーブルに。違反したすべての値をログに記録できないため、existsステートメントを使用したくありません。
どうすればこれを行うことができますか?
これをサポートするように設計されていないため、これにエラーログメカニズムを使用することはできません。テーブルに重複を作成しようとした時点でエラーが発生します(pass_no
10に対して挿入しようとする最初の値はそれ自体で有効です)。そのため、既存のデータと挿入からの複数の値を区別する必要があります。皮切りに。だからあなたはあなた自身を転がす必要があるでしょう。
1つのオプションは、重複を保持する独自のテーブルを作成し、を使用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の影響を受ける列よりも多くの列を作成し、必要に応じて実際のテーブルにのみ挿入するか、「エラー」テーブルにサブセットを挿入できます。各テーブルにこれらの2つの列があるだけで、次のようになります。
select * from tbl_target;
CUS_NO PASS_NO
---------- ----------
103 20
select * from tbl_target_dup;
CUS_NO PASS_NO
---------- ----------
101 10
102 10
同じに基づく2つの挿入で同じことを行うことができますselect
。一方は、両方のカウントが1であることをチェックするサブクエリを使用し、もう一方は、少なくとも1つがそうでないことをチェックしますが、これはパフォーマンスが向上する可能性があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加