CLR触发器仅特定列更新

时间:2012-02-22 22:54:46

标签: c# sql-server sqlclr

每当新文件插入到我的表中然后将值传递给我的WCF服务时,我写了一个clr触发器,现在我必须将进程更改为“更新”只有特定列得到更新然后我必须拉来自其他两个表的值。

我只是想知道这是否仍然可以启动clr触发器只是特定列更新?

像这样的场景

表1:客户详细信息(Cust.No,Cust.Name,Desc)
表2:地址(DoorNo,Street,City,State)。

这里尝试做的是,如果Table1中的“Desc”列更新,则clr触发器被触发并根据“Desc”传递Table1和Table2中的所有值。

这是我的插入代码:

[Microsoft.SqlServer.Server.SqlTrigger(Name = "WCFTrigger",Target = "tbCR", Event = "FOR UPDATE, INSERT")]
public static void Trigger1()
{
    SqlCommand cmd;
    SqlTriggerContext myContext = SqlContext.TriggerContext;
    SqlPipe pipe = SqlContext.Pipe;
    SqlDataReader reader;

    if(myContext.TriggerAction== TriggerAction.Insert)
    {
        using (SqlConnection conn = new SqlConnection(@"context connection=true"))
        {
            conn.Open();
            //cmd = new SqlCommand(@"SELECT * FROM tbCR", conn);
            cmd = new SqlCommand(@"SELECT * FROM INSERTED", conn);
            reader = cmd.ExecuteReader();
            reader.Read();
            //get the insert value's here
            string Cust.No, Cust.Name,Desc;
            Cust.No = reader[0].ToString();
            Cust.Name = reader[1].ToString();
            Desc = reader[2].ToString();
            myclient.InsertOccured(Cust.No, Cust.Name,Desc);
            reader.Dispose();
        }
    }
}

1 个答案:

答案 0 :(得分:3)

您无法有选择地阻止运行触发器,无论列更新,它都将始终运行。但是,一旦启动,您可以参考COLUMNS_UPDATED()功能:

  

返回表示表中列的varbinary位模式   或插入或更新的视图。使用COLUMNS_UPDATED   Transact-SQL INSERT或UPDATE触发器体内的任何位置   测试触发器是否应该执行某些操作。

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

话虽如此,从SQLCLR调用WCF是一个非常糟糕的主意。从触发器调用WCF甚至更糟。您的服务器将在生产中死亡,因为事务将阻止/中止等待某些HTTP响应以通过线路爬回。更不用说由于您无法撤消HTTP调用,因此存在回滚时您的调用本质上是不正确的。执行此类操作的正确方法是通过队列解耦操作和WCF调用。您可以使用tables used as queues执行此操作,可以使用true queues,也可以使用Change Tracking。这些中的任何一个都允许您解除更改和WCF调用,并允许您从单独的进程进行调用,而不是从SQLCLR进行调用

相关问题