Каскадное удаление связанных данных

В базе данных ORACLE нужно удалить запись из таблицы, но существуют связанные записи в других таблицах. В таких случаях при попытке удаления получаем ошибку ORA-022292.

Как удалить все связанные записи?

Скрипт, который в DBMS_OUTPUT выводит команды на удаление всех связанных записей:

-- see dbms_output 
--
declare
procedure gen_delete_cascade (vTableName varchar2, vCond varchar2 default '1=1', iter integer default 15) as
child_record_found EXCEPTION;
pragma EXCEPTION_INIT(child_record_found, -2091);
CURSOR curRel (tablename varchar) IS 
  select r_ucc.column_name source_table_column,
       l_con.table_name depend_table_name,
       l_ucc.column_name depend_table_column
  FROM ALL_CONSTRAINTS l_con
JOIN all_CONSTRAINTS r_con ON r_con.CONSTRAINT_NAME=l_con.r_CONSTRAINT_NAME
JOIN all_cons_columns l_ucc ON l_con.constraint_name = l_ucc.constraint_name
JOIN all_cons_columns r_ucc ON r_con.constraint_name = r_ucc.constraint_name
WHERE r_con.table_name =upper(tablename)
and l_con.constraint_type = 'R';
sql_stmt varchar2(4000);
res integer;
BEGIN
if iter < 1 then
DBMS_OUTPUT.PUT_LINE('-- iteration limit');
return;
end if;
for vCur in curRel(vTableName) loop
sql_stmt := vCur.depend_table_column||' IN (SELECT '
||vCur.source_table_column
||' FROM '
||vTableName
||' WHERE '||vCond||')';
EXECUTE immediate 'select count(*) from '
||vCur.depend_table_name
||' WHERE '||sql_stmt into res;
if res > 0 then
  gen_delete_cascade(vCur.depend_table_name, sql_stmt, iter-1);
  DBMS_OUTPUT.PUT_LINE('-- count='||res);
end if;
end loop;
sql_stmt := 'DELETE FROM '
    ||vTableName
    ||' WHERE '||vCond||';';
dbms_output.put_line(sql_stmt);
--EXECUTE immediate sql_stmt;
END gen_delete_cascade;
BEGIN
DBMS_OUTPUT.ENABLE(buffer_size => NULL);
gen_delete_cascade(upper( '&TABLE' ), '&WHERE');
end;
Опубликовано 30.11.2016