CLR 支援 DML(資料操作)與 DDL(資料定義)兩種觸發器。但一般不建議在觸發器中使用 CLR 執行耗時操作(如發送郵件),因觸發器屬於交易範圍,外部等待時間會計入交易,嚴重影響並發效能。
針對 pubs 資料庫 authors 資料表的 INSERT、UPDATE、DELETE 操作,輸出對應動作名稱。
[Microsoft.SqlServer.Server.SqlTrigger(
Name = "UF_DML_Trigger",
Target = "dbo.authors",
Event = "FOR INSERT, UPDATE, DELETE")]
public static void UF_DML_Trigger()
{
switch (SqlContext.TriggerContext.TriggerAction)
{
case TriggerAction.Insert:
SqlContext.Pipe.Send("Trigger Insert");
break;
case TriggerAction.Update:
SqlContext.Pipe.Send("Trigger Update");
break;
case TriggerAction.Delete:
SqlContext.Pipe.Send("Trigger Delete");
break;
default:
break;
}
}
禁止刪除 pubs 資料庫上的預存程序,嘗試刪除時自動回滾。
[Microsoft.SqlServer.Server.SqlTrigger(
Name = "UF_DDL_Trigger",
Target = "pubs",
Event = "DropProcedure")]
public static void UF_DDL_Trigger()
{
switch (SqlContext.TriggerContext.TriggerAction)
{
case TriggerAction.DropProcedure:
try
{
Transaction trans = Transaction.Current;
trans.Rollback();
SqlContext.Pipe.Send("Drop Proc has Rollback");
}
catch (SqlException ex)
{
// 捕獲預期例外
}
break;
default:
break;
}
}
組件建立方法請參閱前文章。部署觸發器:
-- DML 觸發器
CREATE TRIGGER UF_DML_Trigger
ON dbo.authors
FOR INSERT, UPDATE, DELETE
AS EXTERNAL NAME CLRDemoAssembly.Triggers.UF_DML_Trigger;
GO
-- DDL 觸發器(資料庫範圍)
CREATE TRIGGER UF_DDL_Trigger
ON DATABASE
FOR DROP_PROCEDURE
AS EXTERNAL NAME CLRDemoAssembly.Triggers.UF_DDL_Trigger;
GO
包含所有 DDL/DML 事件動作,如 Insert、Update、Delete、CreateTable、DropProcedure、AlterIndex、GrantStatement 等 100 餘項。完整列表請參考原文件或 MSDN 文件。
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
using System.Transactions;
public partial class Triggers
{
[Microsoft.SqlServer.Server.SqlTrigger(
Name = "UF_DML_Trigger",
Target = "dbo.authors",
Event = "FOR INSERT, UPDATE, DELETE")]
public static void UF_DML_Trigger()
{
switch (SqlContext.TriggerContext.TriggerAction)
{
case TriggerAction.Insert:
SqlContext.Pipe.Send("Trigger Insert"); break;
case TriggerAction.Update:
SqlContext.Pipe.Send("Trigger Update"); break;
case TriggerAction.Delete:
SqlContext.Pipe.Send("Trigger Delete"); break;
default: break;
}
}
[Microsoft.SqlServer.Server.SqlTrigger(
Name = "UF_DDL_Trigger",
Target = "pubs",
Event = "DropProcedure")]
public static void UF_DDL_Trigger()
{
switch (SqlContext.TriggerContext.TriggerAction)
{
case TriggerAction.DropProcedure:
try
{
Transaction.Current.Rollback();
SqlContext.Pipe.Send("Drop Proc has Rollback");
}
catch (SqlException) { }
break;
default: break;
}
}
}