【发布时间】: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