博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
创建触发器,将数据库中表的修改记录进日志表
阅读量:4695 次
发布时间:2019-06-09

本文共 5669 字,大约阅读时间需要 18 分钟。

要求:

假定有一个数据库,有10张表,每张表都有inputuser和createtime,modifyuser,modifytime 4个字段用来记录数据库记录的变动

请为该数据库建立一个日志表,可以记录每个字段的修改情况,日志信息包括创建、修改的用户以及时间,字段名名等信息
并为10张表创建触发器,自动记录日志
触发器的创建要求采用一段通用的代码自动为所有的表创建触发器

备注:

所有以'Table_Log_%'的表为10个对象表

表  FieldModifyLog 为修改的字段信息  包括字段名,修改前的值,修改后的值

表  LogRecords 包含字段 被修改的表名  inputuser createtime modifyuser modifytime  被修改的列(即为表FieldModifyLog)

1 declare @count int ,---表的个数  2 @i int ,---控制循环的次数  3 @tName nvarchar(50),----表名      4 @sql nvarchar(max),---用于插入的触发器语句  5 @sqlUpdate nvarchar(max),---用于更新的触发器语句  6 @sqlDropTriggerUpdate nvarchar(max), ---删除已存在触发器  for  update  7 @sqlDropTrigger nvarchar(max)----删除已存在触发器  for insert  8   9 set @i=0 10 ---得到表的个数 11 select @count= count(*) from dbo.sysobjects where type='u' and name like 'Table_Log_%' 12  13  14 ----循环为每个表创建触发器 15 while @i<@count 16 begin 17     set @i=@i+1  18     ---获得当前的表名 19     select @tName=[name] from (select row_number()over(order by [name]) as hanghao, name from dbo.sysobjects where type='u' and name like 'Table_Log_%') as tt where hanghao=@i 20  21  22     ---判断insert触发器是否存在,若存在删掉 23     if   exists(select * from dbo.sysobjects where Name ='Log_'+ @tName +'_Insert' AND type = 'TR') 24     begin 25     set @sqlDropTrigger='drop trigger Log_'+@tName+'_Insert' 26     exec(@sqldropTrigger) 27     end 28  29  30     ---拼接创建触发器for  insert 语句 31     set @sql='create trigger Log_'+@tName+'_Insert on '+ @tName+'  32     for insert  33     as  34     begin 35     declare @InputUser nvarchar(50),@CreateTime datetime 36     select  @InputUser=[InputUser], @CreateTime=[CreateTime] from inserted 37     insert into LogRecords(TableName,InputUser,CreateTime) values('''+@tName+''',@InputUser,@CreateTime) 38     end'   39  40  41     ---判断update触发器是否存在,若存在删掉 42     if  exists(select * from dbo.sysobjects where Name ='Log_'+@tName+'_Update' AND type = 'TR') 43     begin 44     set @sqlDropTriggerUpdate='drop trigger Log_'+@tName+'_Update' 45     exec(@sqlDropTriggerUpdate) 46     end 47  48  49     --拼接创建触发器for  update 语句 50     set @sqlUpdate=' 51     ----创建触发器 52     create trigger Log_'+@tName+'_Update on '+ @tName +' 53     for update 54     as 55     begin 56         declare @UpdateUser nvarchar(50), 57         @ModifyTime datetime , 58         @fieldCount int,---字段个数 59         @BeforeModifyValue nvarchar(50), 60         @AfterModifyValue nvarchar(50), 61         @currentFieldID int ,----当前刚刚插入到FieldModifyLog里的id 62         @fieldName nvarchar(50),----列名 63         @InputUser nvarchar(50), 64         @CreateTime datetime 65         ----获得列名 66         select @fieldCount=count(*) from syscolumns where id=object_id('''+@tName+''') 67  68         ---循环每列  69         while @fieldCount>0 70         begin 71  72             ---1.首先判断是否有更新, 73             if substring( columns_updated() , (@fieldCount-1)/8+1 , 1 ) & power( 2, (@fieldCount-1)%8 ) > 0 74             begin 75                 ---2.若有更新,获得列名 76                 set @fieldName=(select col_name(object_id('''+@tName+'''),@fieldCount)) 77  78                 ---3.判断被修改的列是不是''ModifyUser'',''ModifyTime'',若不是则向日志表中插入相关记录 79                 if(@fieldName not in(''ModifyUser'',''ModifyTime'')) 80                 begin 81  82                     --3.1.1 判断关于deleted的临时表是否存在,若存在删除 83                     if exists (select * from tempdb.dbo.sysobjects where id = object_id(N''tempdb..#backDel'') and type=''U'') 84                     begin 85                       drop table #backDel 86                     end 87  88  89                     --3.1.2填充deleted临时表 90                     select * into #backDel from  deleted  91  92                     --3.1.3得到更新前的值 93                     declare @sqlBeforeModify nvarchar(max),@outPutBefore nvarchar(50) 94                     set @sqlBeforeModify=N''select @BeforeModifyValue=''+@fieldName+N''   from #backDel'' 95                     exec sp_executesql @sqlBeforeModify,N''@BeforeModifyValue nvarchar(50) output'',@outPutBefore output 96  97  98                     --3.2.1 判断关于inserted临时表是否存在,若存在,则删除 99                     if exists (select * from tempdb.dbo.sysobjects where id = object_id(N''tempdb..#backInsert'') and type=''U'')100                     begin101                          drop table #backInsert102                     end103                     104 105                     --3.2.2填充临时表106                     select * into #backInsert from  inserted107 108                     --3.2.3得到更新后的值109                     declare @sqlAfterModify nvarchar(max),@outPutAfter nvarchar(50)110                     set @sqlAfterModify=''select @AfterModifyValue=''+@fieldName+'' from #backInsert''111                     exec sp_executesql @sqlAfterModify,N''@AfterModifyValue nvarchar(50) output'',@outPutAfter output112 113                     select @UpdateUser=ModifyUser,@ModifyTime=ModifyTime,@InputUser=InputUser,@CreateTime=CreateTime from '+@tName+'114 115                     --3.3向日志表中插入116                     insert into FieldModifyLog values(@fieldName,@outPutBefore,@outPutAfter)117                     set @currentFieldID=IDENT_CURRENT(''FieldModifyLog'')118                     insert into LogRecords(TableName,ModifyUser,ModifyTime,ModifyField,InputUser,CreateTime) values('''+@tName+''',@UpdateUser,@ModifyTime,@currentFieldID,@InputUser,@CreateTime)119                 end------end注释3.120 121             end----end注释1.122             set @fieldCount=@fieldCount-1123 124         end---end循环列的while循环125 126     end ---end触发器的创建 127     '128 129     exec(@sqlUpdate)130 131     ----执行创建语句132 133 134     exec(@sql)135 end136 137 138
View Code

转载于:https://www.cnblogs.com/NoteofEveryDay/archive/2013/05/27/trigger_logtable.html

你可能感兴趣的文章
HTML列表
查看>>
Redis集群创建报错
查看>>
DispacherServlet 的作用
查看>>
POJ - 1426(Find The Multiple)
查看>>
一张图带你看懂原始dao与SQL动态代理开发的区别-Mybatis
查看>>
2016年10月30日--JavaScript语法
查看>>
MiCode 40: 找小“3”
查看>>
四则运算1.0版本
查看>>
leetcode - Longest Consecutive Sequence
查看>>
20165214 2018-2019-2 《网络对抗技术》Exp5 MSF基础应用 Week8
查看>>
JAVA-多线程
查看>>
常用加密算法
查看>>
MYSQL培训准备(2):MYSQL自增长陷阱
查看>>
IDEA 创建普通的maven+java Project
查看>>
背包专题练习
查看>>
Python学习笔记(二)
查看>>
T-SQL: Create folders in remote server by sql statement
查看>>
linux SVN安装及配置教程
查看>>
poj1088 滑雪问题 dfs写法
查看>>
C# DataTable.Select()方法,条件中使用类型转换
查看>>