sto*_*oic 2 sql sql-server audit triggers
我有一个用户表,其中包含| Firstname | Surname | DateOfBirth | ......以及其他一些专栏.在该特定表上,我有一个更新触发器,如果有人更改任何用户值,它会创建审计.
我的问题是,管理层想要通过以下方式显示可视化审计:
DateChanged |Change |Details
--------------------------------------------------------------------------------
2010/01/01 |FirstName Changed |FirstName Changed from "John" to "Joe"
2010/01/01 |FirstName And Lastname Changed|FirstName Changed from "Smith" to "White "And Lastname changed from "els" to "brown"
2010/01/01 |User Deleted |"ark Anrdrews" was deleted
Run Code Online (Sandbox Code Playgroud)
我相信解决这个问题的最佳方法是修改存储过程,但是如何指示触发器记录这些事情呢?
您可以在名为COLUMS_UPDATED()的触发器中调用一个函数.这将返回触发器表中列的位图,其中1表示表中的相应列已被修改.它本身就不那么精彩,因为你最终会得到一个列索引列表,并且仍然需要编写一个CASE语句来确定哪些列被修改.如果你没有很多列可能不那么糟糕,但如果你想要更通用的东西,你可以加入information_schema.columns将这些列索引转换为列名
这里有一个小样本来展示你可以做的事情:
CREATE TABLE test (
ID Int NOT null IDENTITY(1,1),
NAME VARCHAR(50),
Age INT
)
GO
---------------------------------------
CREATE TRIGGER tr_test ON test FOR UPDATE
AS
DECLARE @cols varbinary= COLUMNS_UPDATED()
DECLARE @altered TABLE(colid int)
DECLARE @index int=1
WHILE @cols>0 BEGIN
IF @cols & 1 <> 0 INSERT @altered(colid) VALUES(@index)
SET @index=@index+1
SET @cols=@cols/2
END
DECLARE @text varchar(MAX)=''
SELECT @text=@text+C.COLUMN_NAME+', '
FROM information_schema.COLUMNS C JOIN @altered A ON c.ordinal_position=A.colid
WHERE table_name='test'
PRINT @text
GO
------------------------------------------------------
INSERT test(NAME, age) VALUES('test',12)
UPDATE test SET age=15
UPDATE test SET NAME='fred'
UPDATE test SET age=18,NAME='bert'
DROP TABLE test
Run Code Online (Sandbox Code Playgroud)