| 特性 | AFTER (FOR) | INSTEAD OF |
|---|---|---|
| 觸發時機 | DML 完成、約束檢查通過後 | 取代 DML 動作,基底表不自動修改 |
| 適用物件 | 僅資料表 | 資料表、視圖 |
| 典型用途 | 稽核、衍生資料維護、複雜驗證回滾 | 多表視圖更新、跨表業務邏輯、攔截 DML |
| 效能 | 較高(原生動作已完成) | 較低(需手動執行 DML) |
視圖 V_CustOrderDetail 聯合 Customers、Orders、OrderDetails、Products。
建立 INSTEAD OF UPDATE 觸發器於視圖:
CREATE TRIGGER V_CustOrderDetail_Upd ON V_CustOrderDetail INSTEAD OF UPDATE AS
BEGIN
-- 1. 更新 Customers
UPDATE C SET ContactName = I.ContactName, Phone = I.Phone
FROM Customers C JOIN Inserted I ON C.CustomerID = I.CustomerID;
-- 2. 更新 Orders
UPDATE O SET OrderDate = I.OrderDate, ShipVia = I.ShipVia
FROM Orders O JOIN Inserted I ON O.OrderID = I.OrderID;
-- 3. 更新 OrderDetails
UPDATE OD SET Quantity = I.Quantity, Discount = I.Discount
FROM OrderDetails OD JOIN Inserted I ON OD.OrderID = I.OrderID AND OD.ProductID = I.ProductID;
END
ROLLBACK TRANSACTION 會回滾整個批次。SAVE TRANSACTION 做存檔點,但需謹慎設計。IF UPDATE(ColName):該欄位出現在 UPDATE 清單中即為真(即使值未變)。COLUMNS_UPDATED():回傳 VARBINARY 位元遮罩,可一次檢查多欄位。IF SUBSTRING(COLUMNS_UPDATED(),1,1) & 0x0F > 0 檢查前 4 欄是否任一更新。