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

SQL Server 2005 觸發器實戰:AFTER UPDATE 捕獲欄位變更與條件處理

     編輯:關於SqlServer

觸發器範本解析

ALTER TRIGGER [dbo].[update_email_template]
ON [dbo].[E3_DICT_TABLE]
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    -- 1. 判斷關注欄位是否被更新
    IF (UPDATE(value))
    BEGIN
        -- 2. 從 deleted/inserted 取得變更前後值
        -- 注意:觸發器為批次觸發,deleted/inserted 可能多列
        -- 此處示範單列處理,實務需用 JOIN/EXISTS 處理多列
        DECLARE @id VARCHAR(MAX), @oldValue VARCHAR(MAX), @newValue VARCHAR(MAX);

        SELECT @id = id, @oldValue = value FROM deleted;
        SELECT @newValue = value FROM inserted WHERE id = @id;

        -- 3. 業務邏輯處理
        IF (@id = '1')
        BEGIN
            PRINT 'ID=1 舊值: ' + @oldValue;
            PRINT 'ID=1 新值: ' + @newValue;
            -- 實際應用:寫入稽核表、發送通知、同步快取等
        END

        IF (@id = '2')
        BEGIN
            -- 其他邏輯
        END
    END
END;

關鍵最佳實務

主題說明
多列處理deleted/inserted 為虛擬表,可能包含多列。切勿直接賦值給標量變數。正確做法:
SELECT i.id, i.value AS new_val, d.value AS old_val FROM inserted i JOIN deleted d ON i.id = d.id;
UPDATE() 函數僅判斷欄位「出現在 SET 子句中」,不代表值真正改變。需比對 `inserted` 與 `deleted` 確認實際變更。
遞迴觸發觸發器內再次更新同表會再次觸發。預設關閉 (`RECURSIVE_TRIGGERS OFF`),若開啟需加防呆邏輯 (如 `TRIGGER_NESTLEVEL()` 或上下文資訊)。
效能考量觸發器在隱含交易中執行,耗時操作 (郵件、HTTP 呼叫、跨資料庫) 會鎖定資源、拉長交易。建議:
① 寫入稽核/佇列表 → 由非同步背景作業處理。
② 使用 `sp_send_dbmail` (非同步) 而非 `xp_sendmail`。
③ 避免 `CURSOR`/`WHILE` 逐列處理,改用集合式操作。
INSTEAD OF 觸發器適用於視圖或需攔截/重寫 DML 邏輯 (如軟刪除、跨表同步)。

完整多列稽核範例

CREATE TRIGGER trg_E3_DICT_TABLE_Audit
ON dbo.E3_DICT_TABLE
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    IF NOT UPDATE(value) RETURN;  -- 快速退出

    INSERT INTO dbo.E3_DICT_TABLE_Audit (id, old_value, new_value, changed_by, changed_at)
    SELECT 
        i.id,
        d.value,
        i.value,
        SUSER_SNAME(),  -- 或 ORIGINAL_LOGIN()
        SYSDATETIME()
    FROM inserted i
    JOIN deleted d ON i.id = d.id
    WHERE ISNULL(i.value, '') <> ISNULL(d.value, '');  -- 僅記錄真正變更
END;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved