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.