遞歸觸發器類型
- 直接遞歸:觸發器內部動作再次觸發同一觸發器 (如:UPDATE 觸發器中執行 UPDATE 同一資料表)。
- 間接遞歸:觸發器動作觸發其他資料表的觸發器,形成鏈路最終回到原觸發器 (A→B→C→A)。
預設行為與啟用控制
| 類型 | 預設 | 啟用方式 |
| 間接遞歸 | ON | sp_configure 'nested triggers', 1 (預設 1) |
| 直接遞歸 | OFF | ALTER DATABASE dbName SET RECURSIVE_TRIGGERS ON |
關鍵限制與安全守則
- 最大遞歸深度 32 層:超過即終止並回滾,防止無限迴圈癱瘓系統。
- ROLLBACK TRANSACTION 會取消所有巢狀觸發器:外層觸發器回滾 → 內層全部中止。
- 嚴格檢測遞歸條件:未加條件判斷的遞歸觸發器極危險,必須有明確終止條件 (如:
IF @@ROWCOUNT = 0 RETURN、IF TRIGGER_NESTLEVEL() > 1 RETURN)。
- 超過 32 層通常表示邏輯錯誤:應檢查迴圈條件或改用非觸發器機制 (如:Service Broker、排程作業)。
- 無法控制觸發初始位置:觸發器總是對整個陳述式觸發,不可針對特定列/行選擇性觸發。
- 間接遞歸預設開啟:若不需要,務必
sp_configure 'nested triggers', 0; RECONFIGURE 關閉,降低意外鏈路風險。
啟用直接遞歸範例
USE master;
GO
ALTER DATABASE MyDB SET RECURSIVE_TRIGGERS ON;
GO
實務建議
- 能用 檢視表 + INSTEAD OF 觸發器 解決業務邏輯,優於遞歸 AFTER 觸發器。
- 複雜衍生計算改用 計算欄位、索引檢視表 或 應用層邏輯。
- 必須使用遞歸時:
- 明確註解遞歸目的與終止條件。
- 單元測試驗證 32 層邊界。
- 部署前在測試環境壓力測試並行觸發場景。