首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 級聯刪除與級聯更新:外鍵 ON DELETE/UPDATE CASCADE 完整指南

     編輯:關於SqlServer

透過外鍵約束的 ON DELETE CASCADE 與 ON UPDATE CASCADE,可在父表刪除/更新主鍵時,自動級聯操作子表關聯行,保證引用完整性並簡化應用代碼。

建表示例:三層級聯 (國家 → 城市 → 買家)

-- 父表:國家
CREATE TABLE Countries (
    CountryId INT PRIMARY KEY
);
INSERT INTO Countries VALUES (1),(2),(3);

-- 子表:城市 (級聯刪除/更新國家)
CREATE TABLE Cities (
    CityId INT PRIMARY KEY,
    CountryId INT NOT NULL REFERENCES Countries(CountryId) 
        ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO Cities VALUES (1,1),(2,1),(3,2);

-- 孫表:買家 (級聯刪除/更新城市)
CREATE TABLE Buyers (
    CustomerId INT PRIMARY KEY,
    CityId INT NOT NULL REFERENCES Cities(CityId) 
        ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO Buyers VALUES (1,1),(2,1),(3,2);

級聯行為演示

1. 刪除國家 1 → 城市 1,2 及買家 1,2 連帶刪除

DELETE FROM Countries WHERE CountryId = 1;
-- 結果:Countries 剩 (2,3);Cities 剩 (3,2);Buyers 剩 (3,2)

2. 更新國家 2 → 20 → 城市 CountryId 同步更新

UPDATE Countries SET CountryId = 20 WHERE CountryId = 2;
-- 結果:Countries (1,20,3);Cities (1,1),(2,1),(3,20);Buyers 無變

語法選項完整列表

動作子句行為
刪除父行ON DELETE CASCADE子表關聯行同步刪除
刪除父行ON DELETE SET NULL子表外鍵列置 NULL (列必須允許 NULL)
刪除父行ON DELETE SET DEFAULT子表外鍵列置默認值 (列必須有 DEFAULT)
刪除父行ON DELETE NO ACTION預設:阻止刪除,拋錯 (等同無級聯)
更新父鍵ON UPDATE CASCADE子表外鍵值同步更新
更新父鍵ON UPDATE SET NULL/DEFAULT/NO ACTION同刪除語義

關鍵限制與陷阱

  • 循環級聯禁止:A→B→C→A 形成環路會報錯;自引用表需小心設計。
  • 觸發器順序:級聯動作觸發 AFTER DELETE/UPDATE 觸發器,順序:父表 → 子表 → 孫表...
  • 效能影響:大批量刪除父表時,級聯會產生大量子表操作、日志、鎖,可能導致阻塞/日志暴增。建議分批刪除或軟刪除標記。
  • MERGE 不觸發:MERGE 語句對目標表的刪除/更新不觸發 級聯動作(SQL Server 行為)。
  • 複制/異動發布:級聯動作不會自動複制到訂閱端,需在訂閱端同樣定義外鍵或用觸發器同步。

查詢現有級聯約束

SELECT 
    fk.name AS FK_Name,
    OBJECT_NAME(fk.parent_object_id) AS ChildTable,
    COL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS ChildCol,
    OBJECT_NAME(fk.referenced_object_id) AS ParentTable,
    COL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS ParentCol,
    fk.delete_referential_action_desc AS OnDelete,
    fk.update_referential_action_desc AS OnUpdate
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id;

最佳實踐建議

  1. 核心主從關係(訂單-明細、部門-員工)建議啟用 CASCADE,資料庫層面守護完整性。
  2. 日志/審計/歷史表禁用 CASCADE,採用軟刪除或應用層控制。
  3. 大批量維護時臨時禁用約束:ALTER TABLE Child NOCHECK CONSTRAINT FK_Name,完畢後 CHECK CONSTRAINT。
  4. 文檔化所有級聯路徑,納入架構評審與災難演練。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved