部門表 `MID_A_TAB` (主表) 與員工表 `MID_B_TAB` (子表),部門刪除時自動刪除該部門下所有員工 (級聯刪除)。
CREATE TABLE mid_a_tab (
a VARCHAR2(20),
b VARCHAR2(10),
detpno VARCHAR2(10) -- 部門編號 (主鍵)
) TABLESPACE users;
CREATE TABLE mid_b_tab (
a VARCHAR2(20),
b VARCHAR2(10),
deptno VARCHAR2(10) -- 部門編號 (外鍵)
) TABLESPACE users;
-- 主表主鍵
ALTER TABLE mid_a_tab ADD CONSTRAINT pk_mid_a_tab PRIMARY KEY (detpno);
-- 子表主鍵 (業務主鍵,非外鍵)
ALTER TABLE mid_b_tab ADD CONSTRAINT pk_mid_b_tab PRIMARY KEY (a);
ALTER TABLE mid_b_tab
ADD CONSTRAINT fk_mid_b_tab_deptno
FOREIGN KEY (deptno)
REFERENCES mid_a_tab (detpno)
ON DELETE CASCADE; -- 關鍵:主表刪除行 → 自動刪除子表關聯行
-- 1. 插入主表部門
INSERT INTO mid_a_tab (a, b, detpno) VALUES ('1', '1', '10');
-- 1 row created.
-- 2. 插入子表員工 (引用部門 10)
INSERT INTO mid_b_tab (a, b, deptno) VALUES ('EMP001', 'Zhang', '10');
INSERT INTO mid_b_tab (a, b, deptno) VALUES ('EMP002', 'Li', '10');
COMMIT;
-- 3. 刪除主表部門 10
DELETE FROM mid_a_tab WHERE detpno = '10';
-- 1 row deleted.
-- 4. 驗證子表員工已級聯刪除
SELECT * FROM mid_b_tab WHERE deptno = '10';
-- no rows selected (級聯生效)
-- 5. 嘗試插入不存在部門的員工 (應報錯)
INSERT INTO mid_b_tab (a, b, deptno) VALUES ('EMP003', 'Wang', '99');
-- ORA-02291: integrity constraint (FK_MID_B_TAB_DEPTNO) violated - parent key not found
| ON DELETE 子句 | 主表刪除行時 | 子表對應行 | 適用場景 |
|---|---|---|---|
| 無 (預設) | 允許刪除 | **報錯 ORA-02292** (child record found) | 嚴禁刪除主表,需先手工清理子表 |
| ON DELETE CASCADE | 允許刪除 | **自動刪除** | 主從強生命週期綁定 (訂單-明細、部門-員工) |
| ON DELETE SET NULL | 允許刪除 | **置 NULL** (前提:FK 列無 NOT NULL) | 從屬關係可解耦 (任務-負責人、文章-分類) |
外鍵約束是 **資料庫層強制實體完整性** 的最後防線。**「主鍵 → 外鍵 → 索引 → ON DELETE 行為」** 四步走標準化建模,配合 **級聯刪除謹慎評估、外鍵列必建索引、大量載入時禁用約束**,能構建既安全又高效的關聯數據架構。