Мне сложно найти простой способ удалить все дочерние записи родительского идентификатора. В дочерних таблицах также могут быть собственные дочерние таблицы, поэтому нам нужно удалить все записи в иерархии. Какой метод проще всего? Я мог бы вручную перейти к каждой дочерней таблице и найти ее дочерние таблицы, а затем создать скрипт, но есть слишком много таблиц и вы хотите знать более простой подход. Любая помощь ценится!Oracle - удалить все дочерние записи для родителя
ответ
Это в значительной степени основные ключи и внешние ключи и предложения, такие как ON DELETE CASCADE
. Если еще не поздно, вы можете попробовать добавить ограничения PK и FK, прежде чем делать какие-либо удаления; то все будет легко.
ADDED: На основании дальнейшего обсуждения. Нижеприведенный запрос может быть использован для поиска всех таблиц-потомков родительской таблицы. Вероятно, запрос может быть улучшен по-разному, но это может быть начальная точка OK.
with f as (
select constraint_name, table_name, r_constraint_name
from user_constraints
where constraint_type = 'R'
),
p as (
select constraint_name, table_name
from user_constraints
where constraint_type = 'P'
),
j (child_table, f_key, parent_table, p_key) as (
select f.table_name, f.constraint_name, p.table_name, f.r_constraint_name
from p join f on p.constraint_name = f.r_constraint_name
union all
select 'EMPLOYEES', (select constraint_name from p
where table_name = 'EMPLOYEES'), null, null from dual
)
select level as lvl, j.*
from j
start with parent_table is null
connect by nocycle parent_table = prior child_table
order by lvl, parent_table, child_table;
«родительским» таблица в данном случае СОТРУДНИКИ и имя появляется дважды на одной и той же линии. Это может быть сделано в переменной привязки, если это необходимо. Я использовал СОТРУДНИКИ (примечание: оно должно быть во всех шапках, потому что это то, как строковые значения хранятся в системных таблицах), потому что я использовал это в стандартной схеме HR; выход:
LVL CHILD_TABLE F_KEY PARENT_TABLE P_KEY
----- ----------------- -------------------- ----------------- -----------------
1 EMPLOYEES EMP_EMP_ID_PK
2 DEPARTMENTS DEPT_MGR_FK EMPLOYEES EMP_EMP_ID_PK
2 JOB_HISTORY JHIST_EMP_FK EMPLOYEES EMP_EMP_ID_PK
3 JOB_HISTORY JHIST_DEPT_FK DEPARTMENTS DEPT_ID_PK
Рассмотрим практический пример. Скажем, у вас есть таблица с именем PARENT_TABLE
:
CREATE TABLE PARENT_TABLE
(ID_PARENT_TABLE NUMBER
CONSTRAINT PK_PARENT_TABLE
PRIMARY KEY
USING INDEX,
PARENT_ATTR_1 NUMBER,
PARENT_ATTR_2 VARCHAR2(100),
BLAH_BLAH_BLAH VARCHAR2(50));
Теперь давайте говорить, что есть ребенок таблица с именем, довольно unoriginally, CHILD_TABLE
:
CREATE TABLE CHILD_TABLE
(ID_CHILD_TABLE NUMBER
CONSTRAINT PK_CHILD_TABLE
PRIMARY KEY
USING INDEX,
ID_PARENT_TABLE NUMBER
CONSTRAINT CHILD_TABLE_FK1
REFERENCES PARENT_TABLE(ID_PARENT_TABLE)
ON DELETE CASCADE,
CHILD_ATTR_1 NUMBER,
WHATEVER VARCHAR2(100));
Это ограничение внешнего ключа CHILD_TABLE_FK1, который действительно делает работу здесь. Когда вы удаляете из PARENT_TABLE, база данных замечает, что CHILD_TABLE_FK1 ссылается на PARENT_TABLE (ID_PARENT_TABLE), поэтому в базе данных говорится: «Хмммм ... Я удаляю строку в PARENT_TABLE, которая имеет значение ID_PARENT_TABLE (допустим) 10 - мне интересно, это любые строки в таблице, названной этим ограничением CHILD_TABLE_FK1, которое также имеет значение ID_PARENT_TABLE 10. Ну, по Юпитеру, есть Wow - что мне делать с этим? Ну, ограничение говорит: «ON DELETE CASCADE» - ah-ha! Поэтому я просто удалю эти строки из CHILD_TABLE, у которых есть значения ID_PARENT_TABLE, которые соответствуют тому, который я удаляю, и все будет правильно с миром, реляционно говорящим ». Теперь, если каскад внешнего ключа указал ON DELETE SET NULL
, тогда значения ID_PARENT_KEY в CHILD_TABLE, которые совпадали с удаляемым, были бы установлены в NULL. Кроме того, если вы не указали параметр ANY ON DELETE
, база данных не знала, что делать - вы не сказали ему, чтобы УДАЛИТЬ соответствующие ссылки, и вы не сказали ему установить соответствующие ссылки на NULL, поэтому он будет бросать руки (образно) и бросать исключение (буквально), потому что у вас не может быть дочернего ключа, чей родитель больше не существует.
Обратите внимание, что вы можете продолжить это, насколько это необходимо. Скажем, у вас есть еще одна таблица GRAND_CHILD_TABLE
который ссылается CHILD_TABLE
:
CREATE TABLE GRAND_CHILD_TABLE
(ID_GRAND_CHILD_TABLE NUMBER
CONSTRAINT PK_GRAND_CHILD_TABLE
PRIMARY KEY
USING INDEX,
ID_CHILD_TABLE NUMBER
CONSTRAINT GRAND_CHILD_TABLE_FK1
REFERENCES CHILD_TABLE(ID_CHILD_TABLE)
ON DELETE CASCADE,
what_EVER VARCHAR2(25));
Теперь, когда вы удалите из PARENT_TABLE CHILD_TABLE_FK1 ограничение будет вызывать совпадающие строки в CHILD_TABLE будут удалены, а GRAND_CHILD_TABLE_FK1 ограничение будет удалять любые строки в GRAND_CHILD_TABLE которого ID_CHILD_TABLE значения соответствуют удаляемым из CHILD_TABLE.
Удачи.
- 1. Удалить все дочерние узлы от родителя?
- 2. Удалите все дочерние записи из записи
- 3. Sql Получить все дочерние элементы родителя
- 4. список ява все дочерние классы родителя
- 5. Objectify - все дочерние элементы данного родителя
- 6. Group By все дочерние записи
- 7. Убить все дочерние процессы родителя, но оставить родителя живым
- 8. Удалить все записи из схемы в oracle pl sql
- 9. Как удалить все дочерние записи, когда родительская запись удалена?
- 10. hibernate удалить ребенка из родителя необходимо получить все дочерние элементы родителя?
- 11. Как найти все дочерние записи для родительской записи в plsql?
- 12. Oracle/SQL - возвращает родительские и дочерние записи
- 13. Невозможно перебрать и удалить дочерние записи
- 14. Как предотвратить удаление родителя, если у него есть дочерние записи?
- 15. Выбрать все дочерние записи по определенному id в mysql
- 16. Удалить все записи nfs4_setfacl
- 17. Удалить все старые записи
- 18. Удалить все связанные записи
- 19. Наведение курсора на дочерние триггеры для родителя?
- 20. specific5 loop дочерние страницы родителя
- 21. Как удалить старые дочерние записи при обновлении родительского объекта
- 22. Python tkinter - как удалить все дочерние элементы?
- 23. Как удалить все дочерние компоненты контейнера?
- 24. Применение фильтров на дочерние записи
- 25. Удалить все дочерние из div по классам
- 26. Как получить все дочерние элементы из одного родителя
- 27. Unskewing дочерние divs родителя div
- 28. Rails: Сохранить дочерние элементы перед сохранением родителя
- 29. JPA: Удалить дочерние объекты
- 30. Получить записи, содержащие все дочерние записи на сервере sql
Да, у нас уже есть внешние ключи. Мне просто нужно знать имена таблиц в иерархии и имена столбцов. Затем я могу написать скрипт, чтобы сначала удалить нижние большинство дочерних таблиц, а затем остальные соответственно. – user3224907
Просто используйте каскадное удаление, как указано в названии @mathguy. Не нужно писать снизу вверх удалений – OldProgrammer
Я думаю, что я понимаю, что такое OP после ... что, если FK не установлены с каскадным удалением? Ему/ей нужен способ перечислить всех потомков, чтобы убедиться, что FK настроены с помощью ON CASCADE DELETE. Для моего собственного изучения я изучаю, как это можно сделать - либо с помощью инструментов (я уверен, что они должны быть), либо с иерархическим запросом для ALL_CONSTRAINTS и ALL_CONS_COLUMNS. – mathguy