Voici un exemple de code pour supprimer les données d'une table parent en cascade sur toutes les tables enfants en utilisant le database_dictionary, je me suis beaucoup amusé à l'écrire;-) Notez la dernière ligne delete from person where pk ='38B567E2909447868ABDDF500B78F2A3'; peut facilement être généralisée. Autre chose à ajouter, ce script ne fonctionne pas si vous avez des contraintes primaires de deux colonnes ou plus...
declare
TYPE cur_typ IS REF CURSOR;
procedure delete_from_sub_table_first(p_current_table_name varchar2, l_parent_key_value varchar2) is
c cur_typ;
child_table_pm_key_value varchar2(255);
begin
for childConsRecord in (select ac.table_name child_table, acc.column_name Child_column, rac.table_name, racc.COLUMN_NAME, (select column_name from ALL_CONS_COLUMNS accpm, all_constraints acpm where accpm.constraint_name = acpm.constraint_name and acpm.CONSTRAINT_TYPE = 'P' and ac.TABLE_NAME = acpm.TABLE_NAME) child_table_pm_key
from ALL_CONS_COLUMNS acc, all_constraints ac, ALL_CONS_COLUMNS racc, all_constraints rac
where acc.CONSTRAINT_NAME = ac.CONSTRAINT_NAME
and ac.CONSTRAINT_TYPE = 'R'
and racc.CONSTRAINT_NAME = rac.CONSTRAINT_NAME
and rac.constraint_name = ac.R_CONSTRAINT_NAME
and rac.table_name = p_current_table_name) loop
OPEN c FOR 'select ' || childConsRecord.child_table_pm_key || ' child_value FROM ' || childConsRecord.child_table || ' where ' || childConsRecord.Child_column || ' = :1' using l_parent_key_value;
LOOP
FETCH c INTO child_table_pm_key_value;
EXIT WHEN c%NOTFOUND;
-- process row here
delete_from_sub_table_first(childConsRecord.child_table, child_table_pm_key_value);
END LOOP;
close c;
EXECUTE IMMEDIATE 'DELETE FROM ' || childConsRecord.child_table || ' where ' || childConsRecord.Child_column || ' = :1' using l_parent_key_value;
end loop;
end;
begin
delete_from_sub_table_first('PERSON', '38B567E2909447868ABDDF500B78F2A3');
delete from person where pk = '38B567E2909447868ABDDF500B78F2A3';
end;
/