【问题标题】:Using a tsql trigger to keep data synced up in two tables使用 sql 触发器在两个表中保持数据同步
【发布时间】:2013-11-25 02:00:47
【问题描述】:

我有一个 Products 表,其中包含一个属性,该属性将由最终用户通过 ERP 更新进行更新。发生这种情况时,我需要将更新复制到另一个表中。我完全没有创建 T-SQL 触发器的经验,但我相信它会实现我的目标。

示例: 在IC_Products 表中:

Productkey = 456
StockLocation = ‘GA-07-A250’

IC_ProductCustomFields 表中(将开始相同,因为我将运行一个脚本来实现它):

Productkey = 456
CustomFieldKey = 13 
Value = ‘GA-07-A250’

IC_Products.StockLocation 列更新时,我希望新IC_ProductCustomFields.Value 中的值也能立即自动更新。
如果在IC_Products 中创建了一条新记录,那么我希望在IC_ProductCustomFields 中也创建一条新记录。

我想知道如何编写触发脚本以及如何实现它。我使用的是 SQL Server 2005。

【问题讨论】:

    标签: tsql sql-server-2005 triggers synchronization


    【解决方案1】:

    你想要这样的东西:

    CREATE TRIGGER [dbo].[tr_Products_SyncCustomFields] ON [dbo].[IC_Products] 
    FOR INSERT, UPDATE
    AS
        -- First, we'll handle the update. If the record doesn't exist, we'll handle that second
        UPDATE IC_ProductCustomFields
        SET Value = inserted.StockLocation
        FROM IC_ProductCustomFields cf
            INNER JOIN inserted -- Yes, we want inserted. In triggers you just get inserted and deleted
                ON cf.Productkey = inserted.Productkey AND CustomFieldKey = 13;
    
        -- Now handle the insert where required. Note the NOT EXISTS criteria
        INSERT INTO IC_ProductCustomFields (Productkey, CustomFieldKey, Value)
        SELECT Productkey, CustomFieldKey, Value
        FROM inserted
        WHERE NOT EXISTS 
        (
            SELECT * 
            FROM IC_ProductCustomFields 
            WHERE Productkey = inserted.Productkey AND CustomFieldKey = 13
        );
    
    GO
    

    我认为,您可以为插入和更新执行单独的触发器,但是如果自定义字段不同步,这也会产生恢复(假设?)不变量的副作用;即使在更新中,如果自定义字段不存在,这也会根据需要插入新记录,使其重新符合您的规范。

    【讨论】:

    • 谢谢多米尼克。这看起来肯定会奏效。我将在测试实例中尝试一下。那么当我执行这个时,它会在那个时候执行吗?如果是这样,如果需要,我将如何删除它?我过去注意到有时触发器会被关闭。我没有参与修复,所以我不知道是什么原因造成的,也不知道解决方案是什么;重新执行代码?
    • 触发器一创建就生效。我不知道在禁用状态下创建触发器的方法,但您可以使用 T-SQL 使用 ENABLE TRIGGERDISABLE TRIGGER 或通过 SSMS(右键单击触发器并选择启用/禁用)来执行此操作。我当然会确保在测试实例中彻底测试您的触发器,当然,正如您所提到的,在将其应用于实时系统之前。我们将触发器与我们的 ERP 系统一起用于类似目的,通常它工作正常,但您需要仔细审查它。
    • 为什么我们不能使用IF (@RowCount = 0) /*DO INSERT HERE*/?看来会更有效。
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多