判断字段是否被更新 新旧数据写入Audit Log表中

insus.net解决这个问题,只有创建另外一个表,将存储用户决定要跟踪的表,以及这个表中需要跟踪的字段。

还要创建另外一个表[audit],就是存储跟踪记录的表:


复制代码 代码如下:

audit

set ansi_nulls on

go

set quoted_identifier on

go

set ansi_padding on

go

create table [dbo].[audit](

[audit_nbr] [int] identity(1,1) not null,

[audittype] [char](1) not null,

[tablename] [nvarchar](128) not null,

[fieldname] [nvarchar](128) null,

[oldvalue] [nvarchar](4000) null,

[newvalue] [nvarchar](4000) null,

[username] [nvarchar](128) null,

[createdate] [datetime] not null,

primary key clustered

(

[audit_nbr] asc

)with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary]

) on [primary]

go

set ansi_padding off

go

alter table [dbo].[audit] with check add check (([audittype]=’d’ or [audittype]=’u’ or [audittype]=’i’))

go

alter table [dbo].[audit] add default (getdate()) for [createdate]

go

解决是谁更新数据,是使用这个方法:在sql触发器或存储过程中获取在程序登录的用户

接下来,为跟踪表写一个更新trigger触发器。

在触发器中访问inserted或deleted的内部临时触发表,会得一个异常invalid object name ‘inserted’ 或是invalid object name ‘deleted’ ,解决此问题,可以参考这篇:

exec(execute)函数访问inserted或deleted的内部临时触发表

下面为表更新触发器(部分),有注释:


复制代码 代码如下:

–@n和@o两个变量,一个存储更新数据值,一个为原有数据值

declare @sql nvarchar(max),@n decimal(18,0),@o decimal(18,0)

–@i变量是用户需要跟踪的字段

set @sql = n’select @n = [‘+ convert(nvarchar(max),@i) +’] from #inserted’

–执行动态sql语句。

execute sp_executesql @sql,

n’@n decimal(18,0) output’,

@n output;

–下面sql代码,是从deleted表中获取原来数据值。

set @sql = n’select @o = [‘+ convert(nvarchar(max),@i) +’] from #deleted’

execute sp_executesql @sql,

n’@o decimal(18,0) output’,

@o output;

–对比两个数据值,更新值与原有值,如果不一样,把数据插入audit log表中。

if (isnull(@n,0) <> isnull(@o,0))

execute [dbo].[usp_audit_insert] ‘u’,'<tablename>’,'<fieldname>’,@o,@n,@username

上面代码还有一个存储过程,原因是如果多表或是一个表有更新或是删除需要把跟踪的数据插入audit log表中时,为了更好维护与代码冗余,因此把插入audit log表的过程,写成一个存储过程:


复制代码 代码如下:

usp_audit_insert

set ansi_nulls on

go

set quoted_identifier on

go

alter procedure [dbo].[usp_audit_insert]

(

@audittype [char](1),

@tablename [nvarchar](128),

@fieldname [nvarchar](128),

@oldvalue [nvarchar](4000),

@newvalue [nvarchar](4000),

@username [nvarchar](128)

)

as

insert into [dbo].[audit]

([audittype],[tablename],[fieldname],[oldvalue],[newvalue],[username])

values

(@audittype,@tablename,@fieldname,@oldvalue,@newvalue,@username)

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐