我写了一个触发器来做审计。要捕获所有更改,我循环遍历列列表。我遇到的问题(请参阅下面的代码),当我试图使用OldValue设置@fieldname时,我会得到实际的字段名。我想得到这个值,所以我不需要明确地命名每个字段(就像我设置NewValue时一样--这是完美的)。试图避免这种情况,因为就像大多数数据库一样,我们有几个字段的表。我被这个语法困住了。想要做这样的事情:
@OldValue = (Select 'd.' + @fieldname from deleted)这是我的密码:
SELECT * INTO #ins FROM inserted
SELECT * INTO #del FROM deleted
SELECT @TableName = N'TESTAUDITTABLE'
SELECT @PKCols = column_name
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
and ku.table_name= @TableName
ORDER BY KU.TABLE_NAME, KU.ORDINAL_POSITION;
SELECT @UserName = SYSTEM_USER
SELECT @UpdateDate = {fn now()}
SELECT @field = 0
SELECT @maxfield = MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName
WHILE @field < @maxfield
BEGIN
SELECT @field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND ORDINAL_POSITION > @field
SELECT @bit = (@field - 1 )% 8 + 1
SELECT @bit = POWER(2,@bit - 1)
SELECT @char = ((@field - 1) / 8) + 1
IF SUBSTRING(COLUMNS_UPDATED(),@char, 1) & @bit > 0 OR @Type IN ('I','D')
BEGIN
SELECT @fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND ORDINAL_POSITION = @field
SELECT @ID = coalesce( i.ORIGREC , d.ORIGREC ) ,
@Type = case
when i.ORIGREC is not null and d.ORIGREC is null then 'Insert' -- insert
when i.ORIGREC is not null and d.ORIGREC is not null then 'Update' -- update
when i.ORIGREC is null and d.ORIGREC is not null then 'Delete' -- delete
end,
@OldValue = (Select @fieldname from deleted),
@NewValue = (Select i.NAME from #ins)
FROM inserted i
FULL join deleted d on d.ORIGREC = i.ORIGREC
SELECT @sql = '
INSERT INTO [dbo].[LE_AUDIT] (
DB_USER,
TableName,
ID,
FieldName,
OldValue,
NewValue,
CHANGEDATE,
TRIG_TYPE)
VALUES (''' + SYSTEM_USER + ''',''' + @TableName +
''',''' + @ID + ''',''' + @fieldname + ''',''' +
@OldValue + ''',''' + @NewValue + ''',''' + @UpdateDate + ''',''' + @Type + ''')'
EXEC (@sql)
print @sql
END
END扳机工作正常。这里是链接的原始来源。https://www.simple-talk.com/sql/database-administration/pop-rivetts-sql-server-faq-no.5-pop-on-the-audit-trail/
我不得不修改它,迫使它与另一个应用程序一起工作。只需要修改一行来捕获值,而不需要在while循环中指定实际的字段名。
发布于 2016-05-05 20:36:19
由于时间不够,所以我无法查看您的代码,但我的回答是基于您的问题:如何获得已删除的值/捕获更改?
就在昨天,我正在读CH的书。8、Itzik的“MicrosoftSQLServer2012T-SQL基本面”,他有一个关于使用OUTPUT子句创建审计表的很好的部分。对我来说,这是一种非常酷和简单的跟踪变化的方法,比如更新或删除。
假设我们有一个包含4列的Orders表: orderid、empid、empid和orderdate。如果我们想要创建一个跟踪delete语句的审计表,代码将是:
DELETE FROM dbo.Orders
OUTPUT
deleted.orderid,
deleted.orderdate,
deleted.empid,
deleted.custid
Into dbo.OrdersAudit
WHERE orderid = '5';此代码将运行delete语句,并将所有值存储到审计表中。输出子句还可用于跟踪插入和更新。据我所知,缺点是您必须将输出子句合并到您的所有过程中。但我甚至没有意识到这个子句,它是超级简单的学习语法。这可能不是你想要的,但当我读到这个条款时,我真的很兴奋,并且看起来是一种跟踪数据更改以进行审计的简单方法。
https://dba.stackexchange.com/questions/137677
复制相似问题