A (parent / child) relationship between 2 tables are defined by a foreign key constraint.
eg:
CREATE TABLE PARENT
(
ID NUMBER PRIMARY KEY
);
Table created.
CREATE TABLE CHILD
(
ID NUMBER PRIMARY KEY,
P_ID NUMBER REFERENCES PARENT(ID)
);
Table created.
SQL> insert into parent values(1);
1 row created.
SQL> insert into parent values(2);
1 row created.
SQL> insert into child values(10, 1);
1 row created.
SQL> insert into child values(11, 1);
1 row created.
SQL> commit;
Commit complete.
SQL> delete from parent where id=2;
1 row deleted.
SQL> delete from parent where id=1;
delete from parent where id=1
*
ERROR at line 1:
ORA-02292: integrity constraint (MYOWNER.SYS_C008616) violated - child record
found
We could delete parent record 2 because there were no child records for this record.
Parent record 1 however has 2 child records, preventing the record from being deleted.
You can query the all_cons_columns view to see what child columns matches the parent columns:
select parentcols.owner||'.'||parent.table_name||'.'||parentcols.column_name||' matches to '||
childcols.owner||'.'||child.table_name||'.'||childcols.column_name
from
all_cons_columns childcols
, all_cons_columns parentcols
, all_constraints child
, all_constraints parent
where childcols.owner='MYOWNER' and childcols.constraint_name='SYS_C008616'
and childcols.owner=child.owner
and childcols.constraint_name=child.constraint_name
and child.r_owner=parent.owner
and child.r_constraint_name=parent.constraint_name
and parent.owner=parentcols.owner
and parent.constraint_name=parentcols.constraint_name
and childcols.position=parentcols.position
order by childcols.position;
MYOWNER.PARENT.ID matches to MYOWNER.CHILD.P_ID
Solution is to first delete the child records before deleting the parent record, or to specify the on cascade delete option on the foreign key:
SQL> drop table child;
Table dropped.
CREATE TABLE CHILD
(
ID NUMBER PRIMARY KEY,
P_ID NUMBER REFERENCES PARENT(ID) on delete cascade
);
Table created.
SQL> insert into child values(10, 1);
1 row created.
SQL> commit;
Commit complete.
SQL> delete from parent where id=1;
1 row deleted.
SQL> select * from child;
no rows selected
What a great resource!
RépondreSupprimer