如何将参数传递给外部(SQLCLR)SQL Server触发器

Viv*_*ipo 5 .net t-sql sql-server sqlclr database-trigger

我创建了一个调用这样的程序集的Trigger:

CREATE TRIGGER Testrigger ON STATION  
FOR INSERT 
AS EXTERNAL NAME assemblytest.[WriteTimeInfile.Program].Testrigger 
Run Code Online (Sandbox Code Playgroud)

该程序集中的.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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望能够作为参数传递创建的行或更新的行,如下所示:

CREATE TRIGGER Testrigger ON STATION  
AFTER INSERT 
AS 
EXTERNAL NAME assemblytest.[WriteTimeInfile.Program].Testrigger (STATION.ID)
Run Code Online (Sandbox Code Playgroud)

我在StackOverflow上发现了一个7年的主题,它告诉我们无法将参数传递给CLR程序集.
我在问最近的SQL Server版本是否可行.

你知道是否有办法,如果是的话怎么办?

Sol*_*zky 3

不,您不能直接将参数传递给 SQLCLR 触发器。但是,您可以通过几种方式间接传递值(与常规 T-SQL 触发器相同):

  1. 本地临时表
  2. 设置上下文信息/上下文信息
  3. 在 SQL Server 2016 或更高版本上:sp_set_session_context / SESSION_CONTEXT

在所有情况下,您都可以通过执行SqlCommand带有输出的aSqlParameter将值拉入 .NET 代码来获取值。(有关使用的信息,请参阅最后的注释)。

inserted但是,如果您只想要和/或表的值deleted,那么这些就不是参数或参数。只是SELECT那些使用 usingSqlCommand作为Context Connection = true连接字符串和 SqlDataReader. 您可以在CLR 触发器的 MSDN 页面的“示例 CLR 触发器”部分中查看相关示例。


关于将值传递给不属于 DML 操作一部分的触发器的注意事项:

虽然这种做法并不常见,但确实存在将一条信息从主上下文传递到事件链中的一个或多个触发器的有效用例。我遇到的两种最常见的情况是:1)将基于应用程序的登录名或用户 ID(不是 SQL Server 的一部分)传递给审计触发器,以了解谁删除了行(因为该信息无法添加到操作中的 ModifiedBy 列DELETE) ),以及 2) 根据条件暂时禁用触发器。是的,这是可能的,而且确实有效。请参阅我在 DBA.StackExchange 上的以下答案: