什么 SqlTrigger 属性,以便仅在一列上指定触发器

本文关键字:一列 触发器 属性 SqlTrigger 什么 | 更新日期: 2023-09-27 18:35:22

对于一个简单的sql-server更新触发器,我可以编写这样的类:

[Microsoft.SqlServer.Server.SqlTrigger (Name="MyTrigger", Target="[dbo].[MyTable]", Event="FOR UPDATE")]
public static void MyTrigger() { //... my code }

但是,如果我只想在一列更新时触发,那会表现为:

create trigger myTrigger
on myTable
for update as
if update(MyColumn)
begin
    -- my code
end

我应该使用哪种Microsoft.SqlServer.Server.SqlTrigger属性?

什么 SqlTrigger 属性,以便仅在一列上指定触发器

也许这会帮助你。

[Microsoft.SqlServer.Server.SqlTrigger (Name="Trigger1", Target="Table1", Event="FOR UPDATE")]
public static void Trigger1()
{
    SqlConnection conn = new SqlConnection("context connection=true;");
    SqlCommand cmd = new SqlCommand("select top 0 * from Table1", conn);
    conn.Open();
    SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SchemaOnly);
    if (SqlContext.TriggerContext.IsUpdatedColumn(dr.GetOrdinal("columnname")))
    {
        SqlContext.Pipe.Send("columnname was updated");
    }
    else
    {
        SqlContext.Pipe.Send("columnname was not updated");
    }
    dr.Close();
    conn.Close();
} 

您无法阻止有选择地运行触发器,无论更新列如何,它都将始终运行。但是,一旦启动,您可以查阅 COLUMNS_UPDATED() 函数:

返回一个变量二进制位模式,该模式指示表中的列 或已插入或更新的视图。使用COLUMNS_UPDATED Transact-SQL INSERT 或 UPDATE 触发器正文内的任何位置 测试触发器是否应执行某些操作。

因此,您将调整触发器逻辑,以便根据更新的列执行适当的操作。

话虽如此,从 SQLCLR 调用 WCF 是一个非常非常糟糕的主意。从触发器调用 WCF 的情况更糟。您的服务器将在生产中死亡,因为事务将阻止/中止等待某些 HTTP 响应以爬回网络。更不用说在存在回滚的情况下,您的调用本质上是不正确的,因为您无法撤消 HTTP 调用。执行此类操作的正确方法是通过队列分离操作和 WCF 调用。您可以使用用作队列的表来执行此操作,也可以使用真正的队列,也可以使用更改跟踪。其中任何一个都允许您分离更改和 WCF 调用,并允许您从单独的进程而不是 SQLCLR 进行调用

来源: CLR 触发器仅特定列得到更新