mardi 27 avril 2010

ORA-02292: integrity constraint (%s.%s) violated - child record

You are trying to delete a record, but one or more child records were found, preventing the delete.
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

1 commentaire: