定義外鍵約束時,可透過 ON DELETE 子句指定父表刪除記錄時,子表外鍵欄位的處理方式。Oracle 支援三種模式,各有適用場景與限制。
| 模式 | 語法 | 行為 | 前置條件 | 適用場景 |
|---|---|---|---|---|
| CASCADE | ON DELETE CASCADE | 父表刪除 → 子表關聯列**同步刪除** | 無 | 主從關係緊密,子資料無獨立意義 (訂單-明細) |
| SET NULL | ON DELETE SET NULL | 父表刪除 → 子表外鍵欄位**設為 NULL** | 子表外鍵欄位**允許 NULL** | 子資料需保留但關聯移除 (員工-部門,員工保留但部門解散) |
| NO ACTION | ON DELETE NO ACTION (預設) | 父表刪除 → 若子表有關聯資料則**拋錯阻擋** | 無 | 嚴格參考完整性,防止誤刪 (商品-庫存) |
-- 建立父表:班級 CREATE TABLE stuclass ( cid NUMBER(4) PRIMARY KEY, cname VARCHAR2(40), num NUMBER(4) ); -- 建立子表:學生,外鍵指定 ON DELETE SET NULL CREATE TABLE stu ( sid NUMBER(4), scode VARCHAR(10), sname VARCHAR(20), cid NUMBER(4) REFERENCES stuclass(cid) ON DELETE SET NULL ); -- 測試資料 INSERT INTO stuclass VALUES (1, 'Oracle班', 35); INSERT INTO stu VALUES (1, 'S001', '小王', 1); -- 刪除父表記錄 DELETE FROM stuclass WHERE cid = 1; -- 結果驗證 SELECT * FROM stuclass; -- 無資料 SELECT * FROM stu; -- SID SCODE SNAME CID -- 1 S001 小王 (null) <-- 外鍵自動設為 NULL
-- 修改外鍵為 CASCADE (需先刪除舊約束) ALTER TABLE stu DROP CONSTRAINT SYS_C0010080; -- 查詢 user_constraints 取得名稱 ALTER TABLE stu ADD CONSTRAINT fk_stu_class FOREIGN KEY (cid) REFERENCES stuclass(cid) ON DELETE CASCADE; -- 重新測試 INSERT INTO stuclass VALUES (1, 'Oracle班', 35); INSERT INTO stu VALUES (1, 'S001', '小王', 1); DELETE FROM stuclass WHERE cid = 1; SELECT * FROM stu; -- 無資料,學生記錄同步刪除
NOT NULL 約束,建立 ON DELETE SET NULL 會報錯 ORA-02299DROP COLUMN 或 MODIFY 型別ON DELETE 等同 NO ACTION,Oracle 不支援 RESTRICT 關鍵字 (PostgreSQL/MySQL 有)SELECT uc.constraint_name, uc.table_name AS child_table, ucc.column_name AS child_column, uc.r_constraint_name AS parent_constraint, ucp.table_name AS parent_table, uc.delete_rule -- CASCADE / SET NULL / NO ACTION FROM user_constraints uc JOIN user_cons_columns ucc ON uc.constraint_name = ucc.constraint_name JOIN user_constraints ucp ON uc.r_constraint_name = ucp.constraint_name WHERE uc.constraint_type = 'R' ORDER BY uc.table_name, uc.constraint_name;
FK_ORDER_CUSTOMER,避免系統生成的 SYS_C00xxxxORA-02292 (子記錄存在) 轉為友善錯誤訊息