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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本文参考: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

 

 

 

 

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
3月前
|
SQL 人工智能 监控
SLS Copilot 实践:基于 SLS 灵活构建 LLM 应用的数据基础设施
本文将分享我们在构建 SLS SQL Copilot 过程中的工程实践,展示如何基于阿里云 SLS 打造一套完整的 LLM 应用数据基础设施。
704 58
|
3月前
|
数据采集 运维 监控
不重启、不重写、不停机:SLS 软删除如何实现真正的“无感数据急救”?
SLS 全新推出的「软删除」功能,以接近索引查询的性能,解决了数据应急删除与脏数据治理的痛点。2 分钟掌握这一数据管理神器。
249 31
|
4月前
|
存储 缓存 Apache
StarRocks+Paimon 落地阿里日志采集:万亿级实时数据秒级查询
A+流量分析平台是阿里集团统一的全域流量数据分析平台,致力于通过埋点、采集、计算构建流量数据闭环,助力业务提升流量转化。面对万亿级日志数据带来的写入与查询挑战,平台采用Flink+Paimon+StarRocks技术方案,实现高吞吐写入与秒级查询,优化存储成本与扩展性,提升日志分析效率。
521 1
|
4月前
|
存储 关系型数据库 数据库
【赵渝强老师】PostgreSQL数据库的WAL日志与数据写入的过程
PostgreSQL中的WAL(预写日志)是保证数据完整性的关键技术。在数据修改前,系统会先将日志写入WAL,确保宕机时可通过日志恢复数据。它减少了磁盘I/O,提升了性能,并支持手动切换日志文件。WAL文件默认存储在pg_wal目录下,采用16进制命名规则。此外,PostgreSQL提供pg_waldump工具解析日志内容。
361 0
|
4月前
|
数据采集 运维 监控
|
6月前
|
存储 NoSQL MongoDB
Docker中安装MongoDB并配置数据、日志、配置文件持久化。
现在,你有了一个运行在Docker中的MongoDB,它拥有自己的小空间,对高楼大厦的崩塌视而不见(会话丢失和数据不持久化的问题)。这个MongoDB的数据、日志、配置文件都会妥妥地保存在你为它精心准备的地方,天旋地转,它也不会失去一丁点儿宝贵的记忆(即使在容器重启后)。
691 4
|
11月前
|
监控 关系型数据库 MySQL
|
存储 安全 关系型数据库
2024 Mysql基础与进阶操作系列之MySQL触发器详解(21)作者——LJS[你个小黑子这都还学不会嘛?你是真爱粉嘛?真是的 ~;以后请别侮辱我家鸽鸽]
MySQL触发器的使用场景之数据完整性约束、如何具体创建person的日志表、触发器与存储过程的对比与选择、触发器的性能和注意事项等具体操作详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
存储 关系型数据库 MySQL
MySQL 中的触发器数量之谜
【8月更文挑战第31天】
268 0

热门文章

最新文章