首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 多表級聯刪除四大方案:建立約束、修改約束、觸發器、手動刪除完整比較

     編輯:Oracle 資料庫相關知識

資料庫設計時為防誤刪常未啟用 ON DELETE CASCADE,但事後需求清理錯誤資料時必須級聯刪除。本文提供四種方案完整語法與適用場景比較。

測試環境:父表 FARTAB、子表 CHILTAB、孫表 GCHILTAB1

CREATE TABLE fartab (far_id NUMBER(10) PRIMARY KEY, far_name VARCHAR2(10));
CREATE TABLE chiltab (chil_id NUMBER(10) PRIMARY KEY, far_id NUMBER(10) REFERENCES fartab(far_id));
CREATE TABLE gchiltab1 (gchil_id NUMBER(10) PRIMARY KEY, chil_id NUMBER(10) REFERENCES chiltab(chil_id));

方案一:建表時直接加 ON DELETE CASCADE(最佳、最簡單)

CREATE TABLE chiltab (
  chil_id NUMBER(10) PRIMARY KEY,
  far_id NUMBER(10),
  CONSTRAINT fk_chil FOREIGN KEY (far_id) REFERENCES fartab(far_id) ON DELETE CASCADE
);

優點:宣告式、效能最好、無額外程式碼。
缺點:需在建表時決定,事後修改較麻煩。

方案二:事後修改約束(DROP + ADD CASCADE)

-- 1. 刪除原外鍵
ALTER TABLE gchiltab1 DROP CONSTRAINT fk_g1;

-- 2. 重建帶 CASCADE
ALTER TABLE gchiltab1 ADD (
  CONSTRAINT fk_g1 FOREIGN KEY (chil_id) REFERENCES chiltab(chil_id) ON DELETE CASCADE
);

注意:
- 預設 VALIDATE 會檢查既有資料,大表可能耗時;若確定資料乾淨可加 NOVALIDATE 後再 VALIDATE。
- 參考欄位必須是 唯一/主鍵。

方案三:觸發器實作(彈性最高、可處理非唯一鍵)

-- 父表 ordercombine,子表 vipform(參考非唯一鍵 formerid)
CREATE OR REPLACE TRIGGER ter_ov
BEFORE DELETE ON ordercombine
FOR EACH ROW
BEGIN
  DELETE FROM vipform WHERE v_id = :OLD.formerid;
END;
/

測試:
DELETE FROM ordercombine WHERE formerid = '1'; → 子表關聯列自動刪除。
優點:邏輯可程式化、參考欄位無需唯一。
缺點:行級觸發器大量刪除時效能較差、維護成本高、易被遺忘。

方案四:手動刪除子表再刪父表(適用簡單雙表、小資料量)

DELETE FROM vipform WHERE v_id = '1';
DELETE FROM ordercombine WHERE formerid = '1';

優點:直觀、無隱性邏輯。
缺點:層級多、資料量大時極易遺漏、易出錯。

方案選型決策表

場景推薦方案備註
新建表、明確需級聯方案一標準做法
既有表、需啟用級聯、參考鍵為主鍵方案二注意 VALIDATE 鎖表
參考非唯一鍵、需複雜邏輯(如條件刪除、記錄日誌)方案三加上 PRAGMA AUTONOMOUS_TRANSACTION 避免遞歸
僅 2 表、資料 < 1 萬筆、一次性清理方案四事後立即移除腳本
超大分區表、需秒級清理交換分區見「大表刪除重複資料」一文

清理後建議

若系統上線後不希望保留 CASCADE 風險,可於清理完成後再次 DROP CONSTRAINT ... ADD CONSTRAINT ... 移除 ON DELETE CASCADE,恢復保護模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved