更新时的SQL Server触发器将整个表插入历史记录

时间:2016-10-24 18:03:58

标签: sql-server triggers onupdate

Gotcha alert re需要帮助调整更新触发器以遵守where子句。

SQL Server 2008.主表有12345行。我的意图是,在更新时,我想在更新完成时仅将正在更新的记录复制到历史表中。在使用where子句进行更新时,我发现触发器正在传输整个表,而不仅仅是受where子句限制的受影响的记录。

Production中的History表与Development没有相同的数据结构,因此我从Select中复制/粘贴了Prod结构。不是SQL Server的大师,我没有注意到我从Dev触发器中错过了from insert并且在Prod的触发器中选择了实际的表名:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE trigger [dbo].[myTable_LogUpdate] 
ON [dbo].[myTable]
FOR UPDATE
AS
    INSERT INTO myTable_Hist ([ID], [FLD_1], ..., [FLD_N], [HIST_DT])
        SELECT 
            [ID], [FLD_1], ..., [FLD_N], GETDATE() AS HIST_DT
        FROM
            [dbo].[myTable] -- <<< this should be FROM inserted
GO

EXEC sp_settriggerorder @triggername=N'[dbo].[myTable_LogUpdate]', @order=N'Last', @stmttype=N'UPDATE'
GO

当我使用where子句运行更新时,例如,5条记录:

USE [myDb]

update myTable 
set FLD_7 = 2 
where FLD_1 = 10 and FLD_2 = 20

在消息中,我收到2条回复:

(12345 rows affected)
(5 rows affected)

并且在历史表之前和之后运行计数(*)表明所有12345行已插入myTable_LogUpdate表(现在很庞大并且迫切需要清理)。

更新我必须删除原始的Prod触发器,因为驱动器的磁盘空间已用完。我的原始帖子中的触发器代码来自Dev,因此它显示的是正确的代码,而不是我在Prod上运行的实际故障触发器代码。任何SO大师都无法回答我的问题,因为OP不是错误。

我更新了OP以反映问题代码是什么,并带有需要进行修正的符号。我重新创建了历史记录表,将触发器修复为from inserted,现在它可以正常工作。

感谢Sean,他的评论引导我了解这个启示。

0 个答案:

没有答案