我有一个通用的clr触发器,可以在插入,更新,删除时附加到不同的表。 e.g。
[Microsoft.SqlServer.Server.SqlTrigger(Event = "FOR UPDATE, INSERT, DELETE")]
public static void TriggerHandle()
{
DataTable dataTable = new DataTable("Test");
SqlTriggerContext myContext = SqlContext.TriggerContext;
try
{
using (SqlConnection conn = new SqlConnection(CONNECTION_STRING))
{
conn.Open();
SqlCommand sqlComm = new SqlCommand();
sqlComm.Connection = conn;
switch (myContext.TriggerAction)
{
case TriggerAction.Insert:
sqlComm.CommandText = "Select *,'inserted' as operation from inserted";
break;
case TriggerAction.Update:
sqlComm.CommandText = "Select *,'updated' as operation from inserted";
break;
case TriggerAction.Delete:
sqlComm.CommandText = "Select *,'deleted' as operation from deleted";
break;
}
dataTable.Load(sqlComm.ExecuteReader(), LoadOption.Upsert);
SqlContext.Pipe.Send(String.Format("The datatable is populated with {0} rows ", dataTable.Rows.Count.ToString()));
}
}
...所以它并不特定于某个表。如何在clr触发器内找到触发器正在更新的sql对象?
答案 0 :(得分:0)
希望这会有所帮助:
SELECT OBJECT_NAME(parent_object_id) [object]
FROM sys.objects
WHERE name = OBJECT_NAME(@@PROCID)
答案 1 :(得分:0)
不,我找到了另一种方式: 基本上,您需要先前的触发器将会话上下文信息设置为某个值(例如)
Create TRIGGER [dbo].[SET_MyContext_CONTEXT_INFO]
ON [dbo].[MyTable]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
DECLARE @Ctx varbinary(128)
SELECT @Ctx = CONVERT(varbinary(128), 'MyTable')
SET CONTEXT_INFO @Ctx
END
GO
EXEC sp_settriggerorder @triggername=N'[dbo].[SET_MyContext_CONTEXT_INFO]',@order=N'First', @stmttype=N'DELETE'
GO
EXEC sp_settriggerorder @triggername=N'[dbo].[SET_MyContext_CONTEXT_INFO]', @order=N'First', @stmttype=N'INSERT'
GO
EXEC sp_settriggerorder @triggername=N'[dbo].[SET_MyContext_CONTEXT_INFO]', @order=N'First', @stmttype=N'UPDATE'
GO
然后clr触发器可以访问上下文以检索此值并找出该表。缺点(如果存在的话)是,如果在同一会话和事务和语句中有两个具有这些触发器的表是修改对象,我不太确定该上下文是否指向正确的表(例如,更新视图)。但是在最常见的场景中,当表格以某种方式一个接一个地更新时,它可以正常工作。