触发器记录表某一个字段数据变化的日志 包括插入insert 修改update 删除delete 操作

简介: 本文参考:http://www.cnblogs.com/lyhabc/articles/3236985.html   --触发器记录表某一个字段数据变化的日志 包括插入insert 修改update 删除delete 操作 2013-6-18-- 建测试表USE [pratice]GOc...

本文参考:http://www.cnblogs.com/lyhabc/articles/3236985.html

 

img_405b18b4b6584ae338e0f6ecaf736533.gif
-- 触发器记录表某一个字段数据变化的日志 包括插入insert 修改update 删除delete 操作 2013-6-18
--
 建测试表
USE  [ pratice ]
GO
create  table sto
(id  int  not  null,     --  主键字段
de  datetime          --  被跟踪的字段
constraint pk_sto  primary  key(id)
)

--  建日志表
create  table log_sto
(logid  int  not  null  identity( 1, 1),   --  日志序号(日志主键)
operate  varchar( 10),                --  操作类型 如Insert,Update,Delete.
id  int,                             --  原表ID(主键)
old_de  datetime,                    --  de字段旧值
new_de  datetime,                    --  de字段新值
spid  int  not  null,                  --  spid
login_name  varchar( 100),            --  登录名
prog_name  varchar( 100),             --  程序名
hostname  varchar( 100),              --  主机名
ipaddress  varchar( 100),             --  IP地址
runsql  varchar( 4000),               --  执行的TSQL代码
UDate  datetime                      --  操作日期时间
constraint pk_logsto  primary  key(logid)
)


--  建跟踪触发器
create  trigger tr_sto
on sto after  update, insert, delete
as
begin
    declare  @di  table(et  varchar( 200),pt  varchar( 200),ei  varchar( max))
    insert  into  @di  exec( ' dbcc inputbuffer(@@spid) ')
  
    declare  @op  varchar( 10)
    select  @op = case  when  exists( select  1  from inserted)  and  exists( select  1  from deleted)
                    then  ' Update '
                    when  exists( select  1  from inserted)  and  not  exists( select  1  from deleted)
                    then  ' Insert '
                    when  not  exists( select  1  from inserted)  and  exists( select  1  from deleted)
                    then  ' Delete '  end
                  
    if  @op  in( ' Update ', ' Insert ')
    begin
    insert  into log_sto
     (operate,id,old_de,new_de,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)
      select  @op,n.id,o.de,n.de, @@spid,
       ( select login_name  from sys.dm_exec_sessions  where session_id = @@spid),
       ( select program_name  from sys.dm_exec_sessions  where session_id = @@spid),
       ( select hostname  from sys.sysprocesses  where spid = @@spid),
       ( select client_net_address  from sys.dm_exec_connections  where session_id = @@spid),
       ( select  top  1  isnull(ei, ''from  @di),
        getdate()
      from inserted n
      left  join deleted o  on o.id =n.id
    end
    else
    begin
      insert  into log_sto
       (operate,id,old_de,new_de,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)
        select  @op,o.id,o.de, null, @@spid,
         ( select login_name  from sys.dm_exec_sessions  where session_id = @@spid),
         ( select program_name  from sys.dm_exec_sessions  where session_id = @@spid),
         ( select hostname  from sys.sysprocesses  where spid = @@spid),
         ( select client_net_address  from sys.dm_exec_connections  where session_id = @@spid),
         ( select  top  1  isnull(ei, ''from  @di),
          getdate()
        from deleted o
    end
end
go


-- > 测试DML操作

--  操作1
insert  into sto(id,de)  values( 1, ' 2012-01-01 05:06:07 ')
go

--  操作2
insert  into sto(id,de)  values( 2, ' 2012-01-01 06:06:07 ')
go

--  操作3
update sto  set de = getdate()  where id = 2
go

--  操作4
update sto  set de = getdate()  where id = 1
go

--  操作5
insert  into sto(id,de)  values( 3, ' 2012-01-01 15:26:37 ')
go

--  操作6
delete sto  where id = 2
GO

SELECT  *  FROM log_sto
View Code

 

 改进版本:1、只记录Update字段时,新老值不一致情况。注意NULL是不能进行比较。需要用到Isnull进行转换后,方可进行比较操作。

 

img_405b18b4b6584ae338e0f6ecaf736533.gif
--  建跟踪触发器
ALTER  trigger tr_sto
on sto after  update, insert, delete
as
begin
    declare  @di  table(et  NVARCHAR( max),pt  NVARCHAR( max),ei  NVARCHAR( max))
    insert  into  @di  exec( ' dbcc inputbuffer(@@spid) ')
  
    declare  @op  varchar( 10)
    select  @op = case  when  exists( select  1  from inserted)  and  exists( select  1  from deleted)
                    then  ' Update '
                    when  exists( select  1  from inserted)  and  not  exists( select  1  from deleted)
                    then  ' Insert '
                    when  not  exists( select  1  from inserted)  and  exists( select  1  from deleted)
                    then  ' Delete '  end
                  
    if  @op  = ' Update '
    -- IF UPDATE(de)  --关键字段发生表更记录。
    -- BEGIN
        BEGIN
        insert  into log_sto
         (operate,id,old_de,new_de,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)
          select  @op,n.id,o.de,n.de, @@spid,
           ( select login_name  from sys.dm_exec_sessions  where session_id = @@spid),
           ( select program_name  from sys.dm_exec_sessions  where session_id = @@spid),
           ( select hostname  from sys.sysprocesses  where spid = @@spid),
           ( select client_net_address  from sys.dm_exec_connections  where session_id = @@spid),
           ( select  top  1  isnull(ei, ''from  @di),
            getdate()
          from inserted n
          left  join deleted o  on o.id =n.id
          WHERE  ISNULL(o.de, '') <> ISNULL(n.de, ''-- 只记录修改字段old值和new值不一样的情况。
          -- WHERE CHECKSUM(o.de)<>CHECKSUM(n.de) 
        END
    -- end
    ELSE  if  @op  = ' Insert '
    begin
    insert  into log_sto
     (operate,id,old_de,new_de,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)
      select  @op,n.id,o.de,n.de, @@spid,
       ( select login_name  from sys.dm_exec_sessions  where session_id = @@spid),
       ( select program_name  from sys.dm_exec_sessions  where session_id = @@spid),
       ( select hostname  from sys.sysprocesses  where spid = @@spid),
       ( select client_net_address  from sys.dm_exec_connections  where session_id = @@spid),
       ( select  top  1  isnull(ei, ''from  @di),
        getdate()
      from inserted n
      left  join deleted o  on o.id =n.id
    end
    else
    begin
      insert  into log_sto
       (operate,id,old_de,new_de,spid,login_name,prog_name,hostname,ipaddress,runsql,UDate)
        select  @op,o.id,o.de, null, @@spid,
         ( select login_name  from sys.dm_exec_sessions  where session_id = @@spid),
         ( select program_name  from sys.dm_exec_sessions  where session_id = @@spid),
         ( select hostname  from sys.sysprocesses  where spid = @@spid),
         ( select client_net_address  from sys.dm_exec_connections  where session_id = @@spid),
         ( select  top  1  isnull(ei, ''from  @di),
          getdate()
        from deleted o
    end
end
go
View Code

 

 

 

 

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
我使用flinkcdc的sql形式进行全量同步,4张表,有两张表数据没进去,看日志,id怎么是null呢?
我使用flinkcdc的sql形式进行全量同步,4张表,有两张表数据没进去,看日志,id怎么是null呢?
117 40
|
4月前
|
Java
如何实现一个高效的二叉搜索树(BST)?请给出时间复杂度分析。 要求:设计一个二叉搜索树,支持插入、删除和查找操作。要求在平均情况下,这些操作的时间复杂度为O(log n)。同时,考虑树的平衡性,使得树的高度保持在对数级别。
如何实现一个高效的二叉搜索树(BST)?请给出时间复杂度分析。 要求:设计一个二叉搜索树,支持插入、删除和查找操作。要求在平均情况下,这些操作的时间复杂度为O(log n)。同时,考虑树的平衡性,使得树的高度保持在对数级别。
34 0
|
1天前
|
人工智能 数据可视化 开发工具
Git log 进阶用法(含格式化、以及数据过滤)
Git log 进阶用法(含格式化、以及数据过滤)
|
2天前
|
机器学习/深度学习 前端开发 数据挖掘
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断(下)
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
73 11
|
3天前
|
监控 JavaScript Java
|
8天前
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断2
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
15 0
|
8天前
|
机器学习/深度学习 前端开发 数据挖掘
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
39 0
|
1月前
|
SQL NoSQL Java
【七】springboot整合AOP实现日志操作
【七】springboot整合AOP实现日志操作
41 0
|
2月前
|
Java
SpringAop实现记录用户操作日志
java实现记录用户操作日志功能
|
4月前
|
SQL 弹性计算 监控
构建多账号云环境的解决方案|多账号云上操作日志统一审计
操作审计(ActionTrail)是阿里云提供的云账号资源操作记录的查询和投递服务,可用于安全分析、资源变更追踪以及合规性审计等场景。企业在阿里云采用多账号的资源结构时,如何满对跨账号跨地域的云上操作日志进行统一归集留存和分析,是企业上云管云过程的必备环节。此次分享为您介绍如何使用操作审计产品进行中心化的审计,提升云上多账号操作的可控可见性,及时发现问题、响应问题,规避潜在风险。
256 0