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

SQL Server 觸發器完整語法與參數詳解:DML、DDL、Logon 三大類型

     編輯:關於SqlServer

觸發器 是針對特定事件自動執行的特殊儲存程序。本文依官方文件整理 DML、DDL、Logon 三類觸發器的完整 CREATE TRIGGER 語法、參數說明與關鍵限制,供開發與審計參考。

一、DML Trigger (資料操作觸發器)


CREATE TRIGGER [schema_name.]trigger_name
ON { table | view }
[ WITH  [ ,...n ] ]
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }
[ WITH APPEND ]
[ NOT FOR REPLICATION ]
AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME  }

 ::= [ ENCRYPTION ] [ EXECUTE AS Clause ]
 ::= assembly_name.class_name.method_name

關鍵參數說明

魔術資料表:inserted / deleted

  • 結構與觸發表相同,儲存變更前/後的列映像
  • INSERT:inserted 有新列,deleted 空
  • DELETE:deleted 有舊列,inserted 空
  • UPDATE:deleted 舊值,inserted 新值
  • 相容層級 ≥ 80 時,INSTEAD OF 觸發器可透過聯接 inserted 更新 text/ntext/image 欄位

二、DDL Trigger (結構定義觸發器)


CREATE TRIGGER trigger_name
ON { ALL SERVER | DATABASE }
[ WITH  [ ,...n ] ]
{ FOR | AFTER } { event_type | event_group } [ ,...n ]
AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME  [ ; ] }

 ::= [ ENCRYPTION ] [ EXECUTE AS Clause ]

範圍與事件

  • ON DATABASE:目前資料庫範圍,捕獲 CREATE_TABLE, ALTER_PROCEDURE, DROP_VIEW 等
  • ON ALL SERVER:實例範圍,捕獲 CREATE_DATABASE, ALTER_LOGIN, CREATE_LOGIN 等
  • event_group:預定義事件群組,如 DDL_TABLE_EVENTS (含 CREATE/ALTER/DROP TABLE)、DDL_PROCEDURE_EVENTS 等
  • 事件資訊透過 EVENTDATA() XML 函數取得 (見文章 72345)

三、Logon Trigger (登入觸發器)


CREATE TRIGGER trigger_name
ON ALL SERVER
[ WITH  [ ,...n ] ]
{ FOR | AFTER } LOGON
AS { sql_statement [ ; ] [ ,...n ] | EXTERNAL NAME  [ ; ] }

 ::= [ ENCRYPTION ] [ EXECUTE AS Clause ]

應用場景

  • 限制特定登入的並發連線數
  • 記錄登入稽核 (IP、時間、應用程式)
  • 阻擋非授權 IP/時段登入
  • 注意:Logon Trigger 失敗會導致登入失敗,邏輯必須極度健壯,建議用 TRY...CATCH 吞掉錯誤

四、CLR 觸發器 (EXTERNAL NAME)

  • 組件必須已在資料庫註冊 (CREATE ASSEMBLY)
  • 方法簽名:public static void MethodName(),無參數、無回傳值
  • 類別名稱若含命名空間需用 [Namespace.ClassName] 或 "Namespace.ClassName" 括起
  • 不支援巢狀類別

五、管理與除錯指令


-- 檢視觸發器定義
EXEC sp_helptext 'trigger_name';
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('trigger_name');

-- 啟用/停用
ENABLE TRIGGER trigger_name ON TABLE;  -- 或 DATABASE / ALL SERVER
DISABLE TRIGGER trigger_name ON TABLE;

-- 刪除
DROP TRIGGER [schema_name.]trigger_name;  -- DML
DROP TRIGGER trigger_name ON DATABASE;    -- DDL Database
DROP TRIGGER trigger_name ON ALL SERVER;  -- DDL Server / Logon

-- 查看觸發器中繼資料
SELECT * FROM sys.triggers WHERE name = 'trigger_name';  -- DML
SELECT * FROM sys.server_triggers WHERE name = 'trigger_name'; -- DDL Server / Logon

六、最佳實務提醒

  1. 避免巢狀觸發:sp_configure 'nested triggers', 0 或觸發器內 IF TRIGGER_NESTLEVEL() > 1 RETURN
  2. 避免遞歸觸發:sp_configure 'recursive triggers', 0 或資料庫屬性關閉
  3. 保持輕量:觸發器執行時間直接影響 DDL/DML 回應延遲,複雜邏輯改非同步 (Service Broker / 佇列表 + Agent 作業)
  4. 權限最小化:使用 EXECUTE AS CALLER 或明確低權限帳號
  5. 文件化:擴充屬性記錄用途、作者、建立日期、相依表
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數說明
schema_nameDML 觸發器所屬結構描述 (表/檢視所在結構描述)
trigger_name觸發器名稱,遵循識別碼規則,不可用 #/## 開頭
table | view目標物件。檢視只能建立 INSTEAD OF 觸發器
FOR | AFTERAFTER:所有動作成功 (含約束、級聯) 後觸發。FOR 為預設別名。檢視不可用 AFTER
INSTEAD OF取代 原觸發動作。每表每事件類型 (I/U/D) 只能有一個。不可用於 WITH CHECK OPTION 的可更新檢視
WITH APPEND相容性選項 (相容層級 ≤ 65),現代版本預設即允許同類型多觸發器
NOT FOR REPLICATION複寫代理執行時不觸發
ENCRYPTION模糊化定義文本,防止發布為複寫品。CLR 觸發器不可用
EXECUTE AS指定執行安全內容 (CALLER/SELF/OWNER/'user')