触发器记录表某一个字段数据变化的日志 包括插入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

 

 

 

 

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
SQL 关系型数据库 MySQL
Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志
Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志
213 0
|
关系型数据库 MySQL 数据库
MySQL数据库——触发器-案例(Insert类型、Update类型和Delete类型)
MySQL数据库——触发器-案例(Insert类型、Update类型和Delete类型)
599 0
|
SQL 关系型数据库 MySQL
⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
⑩⑥ 【MySQL】详解 触发器TRIGGER,协助 确保数据的完整性,日志记录,数据校验等操作。
389 0
|
存储 NoSQL 关系型数据库
undo日志insert,update,delete (1)—mysql进阶(六十四)
undo日志insert,update,delete (1)—mysql进阶(六十四)
|
存储 安全 关系型数据库
2024 Mysql基础与进阶操作系列之MySQL触发器详解(21)作者——LJS[你个小黑子这都还学不会嘛?你是真爱粉嘛?真是的 ~;以后请别侮辱我家鸽鸽]
MySQL触发器的使用场景之数据完整性约束、如何具体创建person的日志表、触发器与存储过程的对比与选择、触发器的性能和注意事项等具体操作详解步骤;举例说明、注意点及常见报错问题所对应的解决方法

热门文章

最新文章