Это отличное упражнение для развития ваших навыков PL / SQL и общих знаний Oracle!
Вам необходимо идентифицировать все ограниченные столбцы во всех таблицах с отношениями, исходящими из вашей основной таблицы. Вы можете получить всю необходимую информацию из двух представлений: ALL_CONSTRAINTS и ALL_CONS_COLUMNS . (Если все таблицы находятся в той же схеме, что и пользователь, выполняющий сценарий, вы можете использовать USER_CONSTRAINTS и USER_CONS_COLUMNS, если хотите)
Этот запрос найдет все ограничения внешнего ключа, которые ссылаются на данную таблицу (CUSTOMER
в этом примере):
SELECT constraint_name, table_name, constraint_type
FROM all_constraints
WHERE constraint_type = 'R'
AND r_constraint_name IN (SELECT constraint_name
FROM all_constraints
WHERE constraint_type IN ('P', 'U')
AND table_name = 'CUSTOMER');
CONSTRAINT_NAME C
------------------------------ -
CUSTOMER_FK1 R
CUSTOMER_FK4 R
CUSTOMER_FK5 R
CUSTOMER_FK3 R
CUSTOMER_FK2 R
Теперь для каждого из результатов этого запроса вы можете использовать столбец CONSTRAINT_NAME
, чтобы получить имя таблицы и столбца, которые можно использовать для написания операторов DELETE, чтобы удалить все дочерние строки во всех дочерних таблицах.
В этом примере показано имя таблицы и столбца для ограничения с именем CUSTOMER_FK1
SELECT table_name, column_name
FROM user_cons_columns
WHERE constraint_name = 'CUSTOMER_FK1'
TABLE_NAME COLUMN_NAME
----------------------------- ------------------------------------
RESERVATION CUSTOMER_UID
Чтобы вы могли сделать, например:
DELETE FROM reservation
WHERE customer_uid = 00153464
или
DELETE FROM reservation
WHERE customer_uid IN (SELECT customer_uid
FROM customer
WHERE customer_type = 'X')
Но ваши дочерние таблицы также имеют дочерние таблицы, поэтому, конечно, вам придется сначала удалить эти дочерние строки (назовите их строками внуков). Предположим, что существует таблица с именем booking_detail, имеющая отношение внешнего ключа к резервированию, ваша команда удаления дляservation_detail может выглядеть следующим образом:
DELETE FROM reservation_detail
WHERE reservation_uid in (SELECT reservation_uid
FROM reservation
WHERE customer_uid IN (SELECT customer_uid
FROM customer
WHERE customer_type = 'X')
И если в booking_detail тоже есть дети ... вы поняли. Конечно, вы можете использовать объединения вместо вложенных запросов, но принцип тот же: чем глубже уровень ваших зависимостей, тем сложнее становятся ваши команды удаления.
Итак, теперь вы знаете, как это сделать, задача состоит в том, чтобы написать общий сценарий PL / SQL, чтобы удалить все дочерние строки, строки внуков, строки правнуков ... (до бесконечности) для любой данной таблицы из вверх дном. Вам нужно будет использовать рекурсию . Должна быть веселая программа для написания!
(Последнее редактирование: удален сценарий; см. Мой другой ответ для окончательного решения.)