Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 检测使用触发器时更新了哪些列的最佳方法_Sql_Sql Server_Triggers_Audit - Fatal编程技术网

Sql 检测使用触发器时更新了哪些列的最佳方法

Sql 检测使用触发器时更新了哪些列的最佳方法,sql,sql-server,triggers,audit,Sql,Sql Server,Triggers,Audit,我有一个用户表,它有| Firstname |姓氏| DateOfBirth |。。。和其他一些专栏。在那个特定的表上,我有一个更新触发器,如果有人更改任何用户值,它将创建一个审计 我的问题是,管理层希望通过以下方式显示可视化审核: DateChanged |Change |Details --------------------------------------------------------------------------------

我有一个用户表,它有| Firstname |姓氏| 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

我认为解决这一问题的最佳方法是修改存储的进程,但如何指示触发器记录此类事件呢?

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,所以我点击了“拒绝”按钮,将其视为无效。好的,我以后会这样做。谢谢