我很難找到一個簡單的方法來刪除父ID的所有子記錄。子表也可以有自己的子表,所以我們需要刪除層次結構中的所有記錄。什麼方法最簡單?我可以手動去每個子表,並找到它的子表,然後創建一個腳本,但有太多的表,想知道更簡單的方法。任何幫助感謝!Oracle - 刪除家長的所有子記錄
回答
這幾乎是什麼主鍵和外鍵和條款喜歡ON DELETE CASCADE
是。如果還不算太晚,您可以在做任何刪除操作之前嘗試添加PK和FK約束;那麼一切都會很容易。
ADDED:基於進一步討論。下面的查詢可用於查找父表的所有後代表。查詢可能在許多方面可能得到改進,但它可能是一個好的起點。
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;
本例中的「父」表是EMPLOYEES,名稱出現兩次,在同一行上。如果需要,可以將其製作爲綁定變量。我使用了EMPLOYEES(注意:它必須全部大寫,因爲這是字符串值存儲在系統表中的方式),因爲我在標準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.那麼,通過Jupiter,有!哇 - 我應該怎麼做呢?約束說'ON DELETE CASCADE' - ah-ha!所以我只是刪除CHILD_TABLE中那些ID_PARENT_TABLE值與我正在刪除的ID_PARENT_TABLE值相匹配的那些行,並且從關係角度來說,所有這些行都與世界是正確的。現在,如果外鍵級聯指定了ON DELETE SET NULL
,那麼CHILD_TABLE中與正被刪除的匹配的ID_PARENT_KEY值將被設置爲NULL。此外,如果您沒有指定ANY ON DELETE
選項,數據庫將不知道該怎麼做 - 您沒有告訴它刪除匹配的引用,並且您沒有告訴它將匹配的引用設置爲NULL,所以它會拋出它的手(比喻)並拋出一個異常(字面意思),因爲你不能有一個父母不在那裏的子鍵。
請注意,您可以根據需要繼續此操作。比方說,你有另一臺GRAND_CHILD_TABLE
它引用CHILD_TABLE
:當您從PARENT_TABLE刪除CHILD_TABLE_FK1約束將導致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));
現在,和GRAND_CHILD_TABLE_FK1約束將在GRAND_CHILD_TABLE其ID_CHILD_TABLE刪除任何行值匹配從CHILD_TABLE中刪除的值。
祝你好運。
- 1. Rais - 如何防止刪除家長的所有子女記錄
- 2. 如何防止刪除家長,如果它有子記錄?
- 3. 如何刪除父記錄時刪除所有子記錄?
- 4. 刪除所有舊記錄
- 5. 從記錄中刪除所有子記錄
- 6. 的Oracle SQL不存在刪除我的所有記錄
- 7. oracle |刪除重複記錄
- 8. Oracle - 刪除重疊記錄
- 9. 刪除家長div
- 10. 刪除除一個重複記錄以外的所有記錄
- 11. 刪除舊記錄,同時保持每個家長的最低記錄數
- 12. 從oracle中刪除所有記錄pl sql
- 13. 有效刪除所有重複記錄
- 14. 刪除所有關聯的記錄
- 15. 刪除NSManagedObjectContext中的所有記錄
- 16. 刪除表中的所有記錄
- 17. CakePHP刪除表中的所有記錄
- 18. 應該刪除頂點所有記錄需要多長時間?
- 19. 刪除子記錄刪除實體中的父記錄
- 20. 從表中刪除所有記錄 - doCMD.RunSQL
- 21. VB.NET LINQ to SQL刪除所有記錄
- 22. Android刪除所有記錄SQLite
- 23. Extjs4 localstorage - 如何刪除所有記錄?
- 24. 刪除所有記錄與JOIN
- 25. MySQL刪除所有記錄未選中
- 26. Perforce刪除所有歷史記錄
- 27. 從mysql表中刪除所有記錄
- 28. 刪除所有Git提交記錄
- 29. 從所有表中刪除記錄ID
- 30. 從臨時表中刪除記錄時將被刪除的所有記錄
是的,我們已經設置了外鍵。我只需要知道層次結構中的表名和引用的列名。然後,我可以編寫腳本,首先刪除最底層的子表,然後分別刪除其餘的子表。 – user3224907
只需使用級聯刪除,如@mathguy所述。沒有必要寫下自下而上的刪除 – OldProgrammer
我想我明白什麼是OP後...如果FK沒有設置級聯刪除?他/她需要一種列出所有後代的方法來驗證FK是否設置了ON CASCADE DELETE。對於我自己的學習,我正在研究如何完成這一任務 - 無論是使用工具(我確定必須有一些),也可以使用針對ALL_CONSTRAINTS和ALL_CONS_COLUMNS的分層查詢。 – mathguy