制約を作成し、違反を例外テーブルに報告しようとします。データを修正し、制約を有効にします。
テストデータを作成する
create table parent (pk integer
,data varchar2(1)
,CONSTRAINT PARENT_PK PRIMARY KEY (PK) ENABLE );
create table child (pk integer
,pk_parent integer
,data varchar2(1)
,CONSTRAINT CHILD_PK PRIMARY KEY (PK) ENABLE );
insert into parent values (1,'a');
insert into parent values (2,'b');
insert into child values (1,1,'a');
insert into child values (2,2,'b');
insert into child values (3,3,'c');
外部キー制約を作成します。
alter table child add constraint fk_parent foreign key(pk_parent) references parent(pk);
SQL Error: ORA-02298: Kan (ROB.FK_PARENT) niet valideren - bovenliggende sleutels zijn niet gevonden.
02298. 00000 - "cannot validate (%s.%s) - parent keys not found"
*Cause: an alter table validating constraint failed because the table has
child records.
*Action: Obvious
「enable novalidate」オプションを使用して外部キーを作成します
alter table child add constraint fk_parent foreign key(pk_parent) references parent(pk) enable novalidate;
table CHILD altered.
insert into child values (4,4,'c');
SQL Error: ORA-02291: Integriteitsbeperking (ROB.FK_PARENT) is geschonden - bovenliggende sleutel is niet gevonden.
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause: A foreign key value has no matching primary key value.
*Action: Delete the foreign key or add a matching primary key.
FK に違反する新しいデータを挿入することはできません。
次に、FK 制約に違反しているテーブル内のデータを修正します。
例外テーブルを作成し、制約を有効にしてみます。
create table exceptions(row_id rowid,
owner varchar2(30),
table_name varchar2(30),
constraint varchar2(30));
ALTER TABLE child ENABLE constraint fk_parent EXCEPTIONS INTO EXCEPTIONS;
Error report:
SQL Error: ORA-02298: Kan (ROB.FK_PARENT) niet valideren - bovenliggende sleutels zijn niet gevonden.
02298. 00000 - "cannot validate (%s.%s) - parent keys not found"
*Cause: an alter table validating constraint failed because the table has
child records.
*Action: Obvious
例外テーブルで問題を確認します。
select * from exceptions;
ROW_ID OWNER TABLE_NAME CONSTRAINT
------ ------------------------------ ------------------------------ ------------------------------
AABA78 ROB CHILD FK_PARENT
AAFAAA
Ow9AAC
select * from child where rowid = 'AABA78AAFAAAOw9AAC';
問題を解決する
delete from child where pk = 3;
1 rows deleted.
ALTER TABLE child ENABLE constraint fk_parent EXCEPTIONS INTO EXCEPTIONS;
table CHILD altered.
制約が有効でデータが正しい