Sql 检测使用触发器时更新了哪些列的最佳方法
我有一个用户表,它有| Firstname |姓氏| DateOfBirth |。。。和其他一些专栏。在那个特定的表上,我有一个更新触发器,如果有人更改任何用户值,它将创建一个审计 我的问题是,管理层希望通过以下方式显示可视化审核:Sql 检测使用触发器时更新了哪些列的最佳方法,sql,sql-server,triggers,audit,Sql,Sql Server,Triggers,Audit,我有一个用户表,它有| Firstname |姓氏| DateOfBirth |。。。和其他一些专栏。在那个特定的表上,我有一个更新触发器,如果有人更改任何用户值,它将创建一个审计 我的问题是,管理层希望通过以下方式显示可视化审核: DateChanged |Change |Details --------------------------------------------------------------------------------
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
我认为解决这一问题的最佳方法是修改存储的进程,但如何指示触发器记录此类事件呢?MS SQL Server有一个更新的函数。它允许您指定一个字段名,以告知是否有任何记录更改了该字段 然而,我的经验是,所期望的功能性常常超过这种通用功能的极限。通常情况下,我只是将插入的伪表连接到删除的伪表,然后自己比较它们
*这种比较假设表具有唯一标识,无论是单个字段还是某种复合键。在名为COLUMS\u 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
哪个数据库管理系统?神谕PostgreSQL。。。根据公认的答案,似乎是SQL Server。标记已添加。@GuillermoGutiérrez在添加此类标记时,请在注释字段中说明原因-我所看到的只是“添加的标记”,因为问题没有表明它是一个dbm多于另一个dbm,所以我点击了“拒绝”按钮,将其视为无效。好的,我以后会这样做。谢谢