2012-02-22 78 views
2

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

我只是想知道的是,无论如何,我可以启动clr触发器只是特定的列更新?

这样

表1中的场景:客户详细信息(Cust.No,Cust.Name,DESC)
表2:地址(DoorNo,街道,城市,州)。

这里试图做什么,如果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(); 
     } 
    } 
} 

回答

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

+0

,非常感谢您的评论,所以最好的解决方法是什么?情况? – Usher 2012-02-23 01:35:56

+0

你在通知什么? – 2012-02-23 01:40:47

+0

我在我的本地机器上通过我的clr触发器调用wcf,并解决了任何问题,但是您的回答让我对生产环境感到恐慌,所以想从Windows服务或c#端的其他任何替代方法中寻找答案。建议我对这些不熟悉,但我有限的时间来完成改变触发过程。 – Usher 2012-02-23 01:52:46