CLR 触发仅更新特定列

发布于 2025-01-08 00:47:09 字数 1324 浏览 4 评论 0原文

每当新文件插入到我的表中时,我都会编写一个 clr 触发器,然后将值传递给我的 WCF 服务,现在我必须将流程更改为“更新”,仅更新特定列,然后我必须从中提取值另外两张桌子。

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

像这样的场景

表 1:客户详细信息(客户编号、客户名称、描述)
表 2:地址(门号、街道、城市、州)。

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

I wrote a clr trigger whenever a new file get inserted in to my table and then pass the value to my WCF service, now i have to change the process to "update" only the particular column get updated then i have to pull the value from other two tables.

Am just wondering is this anyway i can start the clr trigger just only the particular column get updated ?

The scenario like this

Table 1: Customer Details (Cust.No, Cust.Name,Desc)
Table 2: Address (DoorNo,Street,City,State).

Here what am trying to do, if the "Desc" column in Table1 get updated then the clr trigger get triggered and pass all the values in Table1 and Table2 based on the "Desc".

Here is my code for Insert:

[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();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

星星的轨迹 2025-01-15 00:47:09

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

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

因此,您可以调整触发逻辑,以便根据更新的列采取适当的操作。

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

You cannot prevent running the trigger selectively, it will always run no matter the columns updated. However, once launched you can consult the COLUMNS_UPDATED() function:

Returns a varbinary bit pattern that indicates the columns in a table
or view that were inserted or updated. COLUMNS_UPDATED is used
anywhere inside the body of a Transact-SQL INSERT or UPDATE trigger to
test whether the trigger should execute certain actions.

So you would adjust your trigger logic to have appropiate action according to what columns where updated.

That being said, calling WCF from SQLCLR is a very very bad idea. Calling WCF from a trigger is even worse. Your server will die in production as transactions will block/abort waiting on some HTTP response to crawl back across the wire. Not to mention that your calls are inherently incorrect in presence of rollbacks, as you cannot undo an HTTP call. The proper way to do such actions is to decouple the operation and the WCF call by means of a queue. You can do this with tables used as queues, you could use true queues or you could use Change Tracking. Any of these would allow you to decouple the change and the WCF call and would allow you to make the call from a separate process, not from SQLCLR

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文