我可以弄清楚如何从触发器获取更新的字段名称。假设我有客户表,如果客户名称和位置名称已更新,那么我们可以从触发器获取这些字段名称发出以下声明
DECLARE @idTable INT
SELECT @idTable = T.id FROM sysobjects P JOIN sysobjects T ON P.parent_obj = T.id WHERE P.id = @@procid
DECLARE @Columns_Updated VARCHAR(50)
SELECT @Columns_Updated = ISNULL(@Columns_Updated + ', ', '') + name
FROM syscolumns
WHERE id = @idTable
AND CONVERT(VARBINARY,REVERSE(COLUMNS_UPDATED())) & POWER(CONVERT(BIGINT, 2), colorder - 1) > 0
但我也希望新值对于那些字段名称,因为我想在字符串变量中生成更新语句,如
SET @SQL="update customer set cutsname='ALFKI',locname='kolkata' where id=10"
我可以获得cutname&来自上面的sql的locname,但我不知道如何获取这些字段的值。
主要关注的是如何知道值以及如何在字符串变量中构造更新语句,名称为&值。
如果有人分享这个想法,那将是很有帮助的。感谢非常容易我们可以像这样从触发器生成select语句
SET @SQL='SELECT '+@Columns_Updated+' FROM MYTable'
我想必须有一些技巧来生成更新语句,其中更新的列名称来自trigger.if你有任何想法然后plzz与我分享。感谢
答案 0 :(得分:0)
我认为在您的情况下,您需要使用SET CONTEXT_INFO命令。
您可以使用SET CONTEXT_INFO命令将最多128个字节的数据与当前连接相关联。
现在您可以做的是生成一个 UNIQUEIDENTIFIER 并在上下文中设置它。
DECLARE @newId UNIQUEIDENTIFIER, @Ctx VARBINARY(128)
SET @newId = newid()
SELECT @Ctx = CONVERT(VARBINARY(128), @newId)
SET CONTEXT_INFO @Ctx
现在在您的触发器中检索此上下文的值,如此 -
DECLARE @CtxData varchar(128)
SELECT @CtxData = CONVERT(VarChar(128), CONTEXT_INFO())
并将更新后的列及其新值跟踪到触发器中的一个新表(或临时表)中,如下所示 -
IF UPDATE(cutsname)
BEGIN
SET @colName = 'cutsname'
SELECT @colVal = cutsname
FROM inserted
END
INSERT INTO newTable (
ColName
,ColValue
,NewUniqueId
)
VALUES (
@colName
,@colVal
,@CtxData
)
和其他专栏相同。
现在在触发器之外访问此表格,如下所示,在您的SP中跟踪,并在审核表中跟踪。
SELECT *
FROM newTable
WHERE NewUniqueId = @newId -- this @newId is the id which we set in CONTEXT_INFO
就是这样。那么你可以根据你的要求重新定义这个逻辑,如果你发现它太长了。
好的,我已经通过组合INSERTED
和DELETED
虚拟表重新定义了插入查询。
INSERT INTO newTable (
ColName
,ColValue
,NewUniqueId
)
SELECT CASE -- to track column name
WHEN I.cutsname <> D.cutsname
THEN 'cutsname'
ELSE ''
END
,CASE -- to track updated new value
WHEN I.cutsname <> D.cutsname
THEN I.cutsname
ELSE ''
END
,@CtxData
UNION ALL
CASE
WHEN I.locname <> D.locname
THEN 'locname'
ELSE ''
END
,CASE
WHEN I.locname <> D.locname
THEN I.locname
ELSE ''
END
,@CtxData
UNION ALL
CASE
WHEN I.OtherColumn <> D.OtherColumn
THEN 'OtherColumn'
ELSE ''
END
,CASE
WHEN I.OtherColumn <> D.OtherColumn
THEN I.OtherColumn
ELSE ''
END
,@CtxData
FROM INSERTED I
JOIN DELETED D ON I.id = D.id
所以现在没有必要为每一列使用IF UPDATE(colName)
...感谢Aaron Bertrand在评论中指出了更新()。
=============================================== ================================= 除了上述解决方案,您还可以在sql server 2008中使用Change Data Capture功能。
this link.有一篇精彩的文章,至少可以通过它。