码迷,mamicode.com
首页 > 其他好文 > 详细

触发器实现记录操作表的日志

时间:2015-01-22 17:42:25      阅读:335      评论:0      收藏:0      [点我收藏+]

标签:

这个功能我是琢磨了好久,本来我的sqlserver方面的知识深入了解的就不多,关键的难点是用变量代替字段名,然后获取字段在表中存的值,再赋给另外一个变量,
我之所以这么做,因为后面好几处要用到这个字段的名称,我才用变量代替,便于修改,可就是实现花费了很长时间,网上这么方面的资料又少,可终究还是找到了解决方案,
希望大家以后遇到同样的问题不至于头大,把具体的实现分享给大家
CREATE trigger [dbo].[trg_new_course] on [dbo].[course] for insert,delete,update as begin declare @tabname varchar(50), @pkname varchar(20), @pkvalue varchar(20), @opttype int, @optip varchar(20), @optsql varchar(200), @xmlstr nvarchar(500); declare @optinfo nvarchar(500), @id_i int, @id_d int; declare @min_id int, --最小的字段号 @total int, --记录总数 @row_count int, --循环变量 @temp_name varchar(100), --临时字段名 @temp_pre_name varchar(100), --带字段类型前缀的变量 @temp_type varchar(100), --临时字段类型 @temp_value varchar(100), --临时字段值 @xmlnode_value varchar(100), --xml的节点值 @sql_name varchar(100), --sql操作相关的字段 @sql_value varchar(100), --sql操作相关的字段值 @sql nvarchar(200), --存储动态sql @pk_pre_name varchar(20) --带类型前缀的关键字段名 set @sql_name = ‘‘; set @sql_value = ‘‘; set @row_count = 1; set @pkname = id; --关键字名称 set @tabname = course; --操作的表名 set @optinfo = ‘‘; select @id_i=id from inserted; select @id_d=id from deleted; select @temp_type = data_type from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname and column_name = @pkname; if (@temp_type = int) begin set @pk_pre_name = i + @pkname end else if(@temp_type = float) begin set @pk_pre_name = f + @pkname end else if(@temp_type = decimal) begin set @pk_pre_name = d + @pkname end else if(@temp_type = datetime) begin set @pk_pre_name = da + @pkname end else begin set @pk_pre_name = c + @pkname end if @id_i is null and @id_d is not null --删除操作 begin set @pkvalue = @id_d; set @opttype = 1; --若变量的类型不是字符串型 set @pkvalue = convert(varchar(200),@pkvalue); --生成执行删除操作的sql语句 set @optsql = delete from + @tabname + where + @pkname + = + @pkvalue; --生成删除操作字段信息的xml表示 set @optinfo = @optinfo + < + @pkname +>; set @optinfo = @optinfo + @pkvalue; set @optinfo = @optinfo + </ + @pkname +>; end else begin set @pkvalue = @id_i; select * into temps from inserted;--这句必须写动态sql中时找不到inerted这个逻辑表的 select @min_id = max(ordinal_position) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname; select @total = count(1) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname; while(@row_count <= @total) begin select @temp_name = column_name,@temp_type = data_type from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname and ordinal_position = @min_id; if(@temp_type = int) begin declare @temp_in int; SET @sql = select @temp_in = + @temp_name + from temps;; EXEC SP_EXECUTESQL @Sql, N@temp_in int OUTPUT, @temp_in OUTPUT; set @xmlnode_value = convert(varchar(100),@temp_in); set @temp_value = @xmlnode_value; set @temp_pre_name = i + @temp_name; end else if(@temp_type = float) begin declare @temp_inf float; SET @sql = select @temp_inf = + @temp_name + from temps;; EXEC SP_EXECUTESQL @Sql, N@temp_inf float OUTPUT, @temp_inf OUTPUT; set @xmlnode_value = convert(varchar(100),@temp_inf); set @temp_value = @xmlnode_value; set @temp_pre_name = f + @temp_name; end else if(@temp_type = decimal) begin declare @temp_ind float; SET @sql = select @temp_ind = + @temp_name + from temps;; EXEC SP_EXECUTESQL @Sql, N@temp_ind decimal(18,0) OUTPUT, @temp_ind OUTPUT; set @xmlnode_value = convert(varchar(100),@temp_ind); set @temp_value = @xmlnode_value; set @temp_pre_name = d + @temp_name; end else begin declare @temp_inc varchar(200); SET @sql = select @temp_inc = + @temp_name + from temps;; EXEC SP_EXECUTESQL @Sql, N@temp_inc varchar(200) OUTPUT, @temp_inc OUTPUT; set @xmlnode_value = convert(varchar(100),@temp_inc); set @temp_value = ‘‘‘‘ + @xmlnode_value + ‘‘‘‘; set @temp_pre_name = c + @temp_name; end --生成插入/修改操作相关数据信息的xml表示 set @optinfo = @optinfo + < + @temp_pre_name + >; set @optinfo = @optinfo + @xmlnode_value; set @optinfo = @optinfo + </ + @temp_pre_name + >; if @id_i is not null and @id_d is null -- 插入操作 begin --生成插入操作执行的sql语句 if(@temp_name <> @pkname) begin set @sql_name = @sql_name + , + @temp_name; set @sql_value = @sql_value + , + @temp_value; end end else if @id_i is not null and @id_d is not null --更新操作 begin --生成修改操作执行的sql语句 if(@temp_name <> @pkname) begin set @sql_name = @sql_name + , + @temp_name + = + @temp_value; end end select @min_id = ordinal_position from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = course and ordinal_position < @min_id; set @row_count = @row_count + 1; end if @id_i is not null and @id_d is null -- 插入操作 begin --生成执行插入操作的sql语句 set @opttype = 0; set @optsql = insert into + @tabname + ( + substring(@sql_name,2,len(@sql_name)) + ) + values( + substring(@sql_value,2,len(@sql_value)) +); end else if @id_i is not null and @id_d is not null --更新操作 begin --生成执行修改操作的sql语句 set @opttype = 3; set @optsql = update + @tabname + set + substring(@sql_name,2,len(@sql_name)) + where + @pkname + = + @pkvalue; end drop table temps; end set @xmlstr = <?xml version="1.0" encoding="gb2312" ?><root>; set @xmlstr = @xmlstr + <baseinfo>; set @xmlstr = @xmlstr + <opttag> + convert(varchar(3),@opttype) + </opttag>; set @xmlstr = @xmlstr + <opttab> + @tabname + </opttab>; set @xmlstr = @xmlstr + <pkname> + @pk_pre_name + </pkname>; set @xmlstr = @xmlstr + </baseinfo>; set @xmlstr = @xmlstr + <optinfo>; set @xmlstr = @xmlstr + @optinfo; set @xmlstr = @xmlstr + </optinfo>; set @xmlstr = @xmlstr + </root>; select @optip=client_net_address from sys.dm_exec_connections where Session_id=@@spid; if(@pkvalue is null) begin set @pkvalue = -1; end insert into optlog values(@tabname,@pkname,@pkvalue,@opttype,@optip,getdate(),@optsql,@xmlstr); print 操作执行成功; end 红色标注的部分我认识是实现的难点,就是用到了sqlserver的系统存储过程sp_executesql,具体的用法网上有的可以查下,这只是我的一家之言,或许大家还有很好的实现,欢迎大家提意见啊!

 

触发器实现记录操作表的日志

标签:

原文地址:http://www.cnblogs.com/ruishuang208/p/4242133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!