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

SQL Server 觸發器完整指南:建立語法、Inserted/Deleted 表詳解、INSTEAD OF 與 AFTER 差異、視圖觸發器實作

     編輯:關於SqlServer

觸發器是資料庫內建的業務規則執行點。本文系統整理 AFTER 與 INSTEAD OF 觸發器建立語法、INSERTED/DELETED 邏輯表行為、三種 DML 操作下的資料分佈、視圖上 INSTEAD OF 觸發器的欄位對應規則,並提供實戰範例與最佳實務。

一、基本建立語法

CREATE TRIGGER TG_ProjectName
ON Table1
AFTER UPDATE
AS
BEGIN
    UPDATE T2
    SET ProjectName = I.ProjectName
    FROM Table2 T2
    INNER JOIN INSERTED I ON T2.ProjID = I.ID;
END;

二、INSERTED / DELETED 邏輯表完整行為

DML 操作INSERTED 表DELETED 表說明
INSERT新資料列空新列同時寫入 INSERTED 與基底表
DELETE空舊資料列舊列從基底表移至 DELETED
UPDATE新資料列舊資料列相當於 DELETE + INSERT:舊→DELETED,新→INSERTED+基底表

三、AFTER 觸發器限制與注意事項

  • ❌ 無法參考 INSERTED/DELETED 中的 TEXT/NTEXT/IMAGE 欄位 (SQL 2000/2005)。
  • ✅ INSTEAD OF 觸發器可參考上述大型物件欄位。
  • ⚠️ 多列更新需檢查 @@ROWCOUNT 或 IF UPDATE(Col) 判斷影響範圍。
  • ⚠️ 避免在觸發器中發送郵件、呼叫 Web Service 等長耗時操作,阻塞交易。

四、INSTEAD OF 觸發器:攔截並自訂 DML 行為

適用場景

  • 視圖更新 (複雜聯結、衍生欄位、聚合)。
  • 跨表業務規則 (如刪除訂單同步扣減庫存、寫入稽核)。
  • 替代預設行為 (如軟刪除:UPDATE IsDeleted=1 而非真刪除)。

視圖上 INSTEAD OF 觸發器欄位對應規則

CREATE VIEW V_EmpName (EmpID, LName, FName)
AS SELECT EmployeeID, LastName, FirstName FROM Northwind.dbo.Employees;

-- 觸發器接收的 INSERTED/DELETED 結構與視圖 SELECT 清單一致:
-- EmpID (INT), LName (NVARCHAR), FName (NVARCHAR)
-- 複雜運算式 (函數、常數) 會被忽略,觸發器需自行處理。

五、實戰範例:軟刪除 INSTEAD OF DELETE

CREATE TRIGGER TR_SoftDelete_Orders
ON Orders
INSTEAD OF DELETE
AS
BEGIN
    SET NOCOUNT ON;
    UPDATE O
    SET IsDeleted = 1, DeletedAt = SYSDATETIME(), DeletedBy = SUSER_SNAME()
    FROM Orders O
    INNER JOIN DELETED D ON O.OrderID = D.OrderID;
END;

應用層執行 DELETE FROM Orders WHERE OrderID=100 實際執行 UPDATE,資料保留可供稽核/復原。

六、最佳實務檢核清單

  1. ✅ 單一觸發器處理單一業務邏輯,避免巨型觸發器難以維護。
  2. ✅ 使用 SET NOCOUNT ON 減少網路往返。
  3. ✅ 以 INNER JOIN INSERTED/DELETED 替代游標,集合式操作效能佳。
  4. ✅ 交易範圍最小化:觸發器隱含在觸發 DML 的交易中,避免額外 BEGIN TRAN。
  5. ✅ 部署前於 TEST 環境負測,驗證鎖定鏈與死結風險。
  6. ✅ 文件化觸發器用途、觸發條件、修改表範圍,納入版控。

七、版本演進提醒

  • SQL 2005+:MAX(INSERTED.Col) 等聚合可直接用於大型欄位 (VARCHAR(MAX)/VARBINARY(MAX))。
  • SQL 2008+:MERGE 陳述式可觸發觸發器,INSERTED/DELETED 包含合併結果。
  • SQL 2016+:SESSION_CONTEXT 可在觸發器間傳遞資訊。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved