【问题标题】:Replicated record triggers multiple times for a single update一次更新多次触发复制记录
【发布时间】:2025-11-22 00:55:02
【问题描述】:

设置从另一台服务器复制的 SQL Server 2012 表; 更新/插入触发器(在复制表 A 上)在单个记录更新上多次触发;

触发器的内容是:

BEGIN
IF (UPDATE(AdmitDate) AND UPDATE(AdmitTime)) OR (UPDATE(DischargeDate) AND UPDATE(DischargeTime)) --Check to see if any of the relevant conditions have changed
BEGIN --This is automatically true for an insert assumed they were originally null
    BEGIN TRY
        SET NOCOUNT ON

        -- Get patient's chartnumber through the inserted record
        SELECT  @ChartNumber = i.ChartNumber FROM inserted i
        SET @DatabaseName=Convert(Varchar(100),DB_NAME())

        SET @user=CURRENT_USER;
        SET @message = 'ChartNumber[' + @ChartNumber+'], Database Name:[' +@DatabaseName+']';
        Execute [sp_APP-Log-Entry]  @user, '5000', 0, 0,  'Trigger on AB_Abstract', '26', @message; -------------------------------------------------------

    END TRY
    BEGIN CATCH
        --IF XACT_STATE() = -1 ROLLBACK;  -- REPLICATION WILL DIE ANYWAY ON ANY ERROR. 
        INSERT INTO X_HUDB.dbo.[App-Response_log]
            VALUES (CONVERT(sysname, CURRENT_USER), ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_STATE(), ERROR_PROCEDURE(), 
                    ERROR_LINE(), ERROR_MESSAGE(), getdate())
    END CATCH
END

结束

怎么会这样?我意识到有 UPDATE 条件,但它应该表明 [sp_APP-Log-Entry] 被调用的次数更少,但现在它为复制记录调用 2 到 7 次,但如果我使用更新查询更新多个字段,则只有一次来自不同数据库实例的非复制表。

(我看不到任何错误,否则会破坏复制)

【问题讨论】:

  • inserted 可以包含 0、1 或 多个 行。 SELECT @ScalarVariable = column FROM inserted 是一个错误的概念。此外,您应该避免命名以sp_ 开头的存储过程。最后,关于您的问题,您是否考虑过将触发器标记为NOT FOR REPLICATION

标签: sql-server sql-server-2012


【解决方案1】:

源系统中的记录被多个业务规则多次更新(在几毫秒内)。事实证明,复制工作得有点过于完美了。

也许墨菲需要见奥卡姆。

尽管如此,我以后会避开链接到触发器的电子邮件或复杂逻辑,它只是被复制的系统是一个包。考虑到不良设计模式固有的不稳定性,每分钟轮询一次使用触发器中的一些元数据对插入/删除的表进行轮询会比实时更可取。

【讨论】: