0

I have a parent table name A and there are 47 child table which are referencing to this parent table A, i want to delete records from 23 child tables and then the parent table as well, and want to keep the records in the remaining child tables.

I tried doing this by disabling and enabling constraint but faced issue while enabling the constraint.

Can anyone suggest any better approach.

NOTE: I am trying to achieve this via shell script.

RT94
  • 13
  • 3
  • *but faced issue while enabling the constraint* so... Should we guess what was the issue or you can provide some specific error code? – astentx Apr 14 '22 at 09:44
  • SQL Error: ORA-02298: cannot validate parent keys not found 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 – RT94 Apr 14 '22 at 10:42

1 Answers1

0

Keyword here is ENABLE NOVALIDATE. It'll let you keep "invalid" existing data, but referential integrity will be enforced for newly added rows.

Here's an example.

Master and two detail tables:

SQL> create table master
  2    (id_mas number primary key,
  3     name varchar2(20));

Table created.

SQL> create table det_1
  2    (id_det number primary key,
  3     id_mas number constraint fk_d1_mas references master (id_mas),
  4     name varchar2(20));

Table created.

SQL> create table det_2
  2    (id_det number primary key,
  3     id_mas number constraint fk_d2_mas references master (id_mas),
  4     name varchar2(20));

Table created.

SQL>

Sample rows:

SQL> insert into master (id_mas, name)
  2  select 1, 'Little' from dual union all
  3  select 2, 'Foot'   from dual;

2 rows created.

SQL> insert into det_1 (id_det, id_mas, name)
  2  select 100, 1, 'Lit det 1'  from dual union all
  3  select 101, 1, 'Tle det 1'  from dual union all
  4  select 102, 2, 'Foot det 1' from dual;

3 rows created.

SQL> insert into det_2 (id_det, id_mas, name)
  2  select 200, 1, 'Lit det 2'  from dual union all
  3  select 201, 2, 'Tle det 2'  from dual union all
  4  select 202, 2, 'Foot det 2' from dual;

3 rows created.

SQL> commit;

Commit complete.

SQL>

Now, let's delete ID_MAS = 1 from DET_1 and MASTER, but keep it in DET_2:

Deleting from detail table is OK (why wouldn't it be?):

SQL> delete from det_1 where id_mas = 1;

2 rows deleted.

I can't delete from master table because of foreign key constraint from DET_2:

SQL> delete from master where id_mas = 1;
delete from master where id_mas = 1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_D2_MAS) violated - child record found

So, let's disable it:

SQL> alter table det_2 disable constraint fk_d2_mas;

Table altered.

Deleting from master now succeeds:

SQL> delete from master where id_mas = 1;

1 row deleted.

Re-enabling previously disabled constraint on DET_2 will fail because it contains row(s) whose ID_MAS doesn't exist in MASTER table any more:

SQL> alter table det_2 enable constraint fk_d2_mas;
alter table det_2 enable constraint fk_d2_mas
                                    *
ERROR at line 1:
ORA-02298: cannot validate (SCOTT.FK_D2_MAS) - parent keys not found

As I said, use ENABLE NOVALIDATE:

SQL> alter table det_2 enable novalidate constraint fk_d2_mas;

Table altered.

Tables' contents:

SQL> select * from master;

    ID_MAS NAME
---------- --------------------
         2 Foot

SQL> select * from det_1;

    ID_DET     ID_MAS NAME
---------- ---------- --------------------
       102          2 Foot det 1

SQL> select * from det_2;

    ID_DET     ID_MAS NAME
---------- ---------- --------------------
       200          1 Lit det 2         --> this master doesn't exist any more
       201          2 Tle det 2
       202          2 Foot det 2

SQL>

Let's try to insert some new (valid and invalid) rows:

SQL> insert into det_1 (id_det, id_mas, name)
  2  select 110, 2, 'Valid' from dual;

1 row created.

SQL> insert into det_1 (id_det, id_mas, name)
  2  select 111, 1, 'Invalid' from dual;
insert into det_1 (id_det, id_mas, name)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.FK_D1_MAS) violated - parent key not
found


SQL> insert into det_2 (id_det, id_mas, name)
  2  select 210, 2, 'Valid' from dual;

1 row created.

SQL> insert into det_2 (id_det, id_mas, name)
  2  select 211, 1, 'Invalid' from dual;
insert into det_2 (id_det, id_mas, name)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.FK_D2_MAS) violated - parent key not
found


SQL>

I am trying to achieve this via shell script.

A shell script? What does shell have to do with that? It is Oracle's business.

Littlefoot
  • 131,892
  • 15
  • 35
  • 57
  • Thanks Littlefoot. I am trying to automate this process by a shell script to fetch the child tables, disable the constarint delete the record from specific child table, then the master table and then enable it back. – RT94 Apr 14 '22 at 10:38