我创建了一个调用如下程序集的触发器:
CREATE TRIGGER Testrigger ON STATION
FOR INSERT
AS EXTERNAL NAME assemblytest.[WriteTimeInfile.Program].Testrigger
该程序集中的 .NET 代码执行如下操作:
namespace WriteTimeInfile
{
public class Program
{
[SqlTrigger(Name = @"Testrigger", Target = "[dbo].[STATION]", Event = "FOR INSERT, UPDATE, DELETE")]
public static void Testrigger()
{
File.AppendAllText(@"C:\Users\Vivien\date.txt",
DateTime.Now.ToString() + Environment.NewLine);
}
}
}
我希望能够将创建的行或更新的行作为参数传递,如下所示:
CREATE TRIGGER Testrigger ON STATION
AFTER INSERT
AS
EXTERNAL NAME assemblytest.[WriteTimeInfile.Program].Testrigger (STATION.ID)
我找到了一个7岁的topic在 StackOverflow 上,它告诉我们无法将参数传递给 CLR 程序集。
我想问的是,在最新的 SQL Server 版本中现在是否可以实现。
你知道是否有办法吗?如果有的话该怎么做?
最佳答案
不,您不能直接将参数传递给 SQLCLR 触发器。但是,您可以通过几种方式间接传递值(与常规 T-SQL 触发器相同):
- 本地临时表
- SET CONTEXT_INFO/CONTEXT_INFO
- 在 SQL Server 2016 或更高版本上:sp_set_session_context/SESSION_CONTEXT
在所有情况下,您都可以通过执行带有输出 SqlCommand
的 SqlParameter
来获取值,以将值提取到 .NET 代码中。 (有关使用的信息,请参阅最后的注释)。
但是,如果您只想要 inserted
和/或 deleted
表的值,那么这些值就不是参数。只是 SELECT
那些使用 SqlCommand
使用 Context Connection = true
作为连接字符串和 SqlDataReader
。您可以在 MSDN 页面的 CLR Triggers 的 Sample CLR Trigger 部分中查看此示例。
有关向不属于 DML 操作的触发器传递值的注意事项:
虽然这不是很常见,但确实存在将一条信息从主上下文传递到事件链中的一个或多个触发器的有效用例。我遇到的两种最常见的情况是:1)将基于应用程序的登录名或用户 ID(不是 SQL Server 的一部分)传递给审计触发器,以了解谁删除了行(因为该信息无法添加到 DELETE
中的 ModifiedBy 列中)操作),以及 2)根据条件暂时禁用触发器。是的,这是可能的,而且确实有效。请参阅我在 DBA.StackExchange 上的以下答案:
关于.net - 如何将参数传递给外部 (SQLCLR) SQL Server 触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41440692/