【问题标题】:SQL Server trigger to check if column value was changed to insertSQL Server 触发器检查列值是否已更改为插入
【发布时间】:2018-09-09 01:43:13
【问题描述】:

我有大约 25 个表,每个表都有 3 个触发器(插入、更新、删除)来生成有关用户操作的日志。每次在 UI 中进行编辑时,所有这些表都会更新,尽管它们的值在 UI 中不会更改。

在这种情况下,我不能只检查列是否更新,我需要检查以前更新的值是否与新更新的值不同,以便我可以插入到我的日志表中。此外,我需要将所有更新的表值作为用逗号分隔的字符串插入到日志表中。

有什么有效的方法来处理这个问题吗?

ALTER TRIGGER [dbo].[Activity_Update]
ON [dbo].[Activity]
AFTER UPDATE
AS
BEGIN
    DECLARE @Names VARCHAR(8000) 
    SET @result = ' '

    DECLARE @id INT;
    SELECT @id = i.ID FROM inserted i;      

    IF UPDATE(deptNotes) 
    BEGIN
        DECLARE @OldValue NVARCHAR(MAX)

        SELECT TOP 1 @OldValue = deptNotes 
        FROM Activity 
        WHERE id = @id 
        ORDER BY Timestamp DESC

        IF (@OldValue != (SELECT i.deptNotes FROM inserted i))        
        BEGIN
            IF ((SELECT i.deptNotes FROM inserted i) != ' ')
               SELECT @result =  @result + ',' + 'Modified dept. Notes'
            ELSE
               SELECT @result =  @result + ',' + 'Removed dept. Notes'
        END
   END

   IF UPDATE(deptActivityID) 
   BEGIN
       DECLARE @OldValue1 NVARCHAR(MAX)

       SELECT TOP 1 @OldValue1 = deptActivityID 
       FROM Activity 
       WHERE id = @id  
       ORDER BY Timestamp DESC

       IF (@OldValue1 != (SELECT i.deptActivityID FROM inserted i))           
       BEGIN
           SELECT @result =  @result + ',' + 'Changed dept. Activity  ' 
       END
    END

    IF UPDATE(SubmissionDate) 
    BEGIN
    declare @OldValue2 nvarchar(max)
    select Top 1 @OldValue2 = submissiondate from [Activity] where id=@id Order by Timestamp DESC

     If (@OldValue2 != (select i.submissiondate from inserted i))         
     BEGIN
     Select @result =  @result + ',' + 'Changed application date - ' + '"' + (select cast(i.submissiondate as nvarchar(500)) from inserted i)+ '"' 
     END
     END


     INSERT [Activity]
     ( 
       [deptActivityID], 
       [deptNotes], 
       [SubmissionDate], 
       [Username], 
       [Operation], 
       [Comment]
       )
       SELECT 
       v.deptActivityID, 
       v.deptNotes, 
       v.SubmissionDate,
       v.[LastEditBy],
       'update', 
       @result
       FROM inserted v
       END
       GO

【问题讨论】:

  • 什么版本的 SQL?
  • Sql Server 2012.
  • 我的意思是开发人员或企业。如果是这两者之一,您可以使用更改数据捕获,并且可能会为自己省去很多麻烦
  • Sql Server 2012 企业版
  • 那么更改数据捕获可能需要研究。基本上,它异步记录您对表所做的所有更改(我知道您说过您只想要各种更改,但除非磁盘空间是您的限制因素,否则您可能只是采用“越多越好”的理念)。您还可以使用一些内置的 CDC 函数找出哪些值发生了变化。

标签: sql sql-server sql-server-2012 triggers


【解决方案1】:

您可以使用deleted 表找出旧值是什么,使用inserted 找出新值。另请注意,INSERT、UPDATE 和 DELETE 可能会影响多行,因此您应该使用触发器来处理。

下面的触发代码将为您提供 deptNotes 中任何更改的行列表。

select  'deptActivityID ' + d.deptActivityID +
        ' Changed from ' + d.deptNotes + ' to ' + i.deptNotes
from    deleted d
        inner join inserted i   on  d.deptActivityID    = i.deptActivityID
where   d.deptNotes <> i.deptNotes

如果你的 deptNotes 可能包含 NULL 值,你需要使用 ISNULL() 来处理

【讨论】:

    猜你喜欢
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多