Audit Logging: Triggers

1. T_ORDER
For Insert: tr_order_i

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'tr_order_i')
    BEGIN
        DROP  Trigger tr_order_i
    END
GO

CREATE Trigger tr_order_i ON dbo.T_ORDER 
AFTER INSERT
AS
IF UPDATE(VERSION_NO)
BEGIN
        INSERT [dbo].[T_AUDIT_LOG_DETAIL]
                ([TRANSACTION_NO]
                ,[TABLE_NAME]
                ,[OPERATION_TYPE]
                ,[DATA_CHANGE])
                
        SELECT INSERTED.TRANSACTION_NO
                , 'T_ORDER'
                ,'Insert'
                ,'<dataChange> <after order_id ="'+CONVERT(VARCHAR,INSERTED.ORDER_ID)+'"' +
                ' order_date="' +CONVERT(VARCHAR,INSERTED.ORDER_DATE) + '"' +
                ' supplier="'+INSERTED.SUPPLIER +'"/></dataChange>'
        FROM  INSERTED       
        WHERE NEED_AUDIT  = 1
        
END  

GO

For Update: tr_order_u

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'tr_order_u')
    BEGIN
        DROP  Trigger tr_order_u
    END
GO

CREATE Trigger tr_order_u ON dbo.T_ORDER 
AFTER UPDATE
AS
IF UPDATE(VERSION_NO)
BEGIN
        INSERT [dbo].[T_AUDIT_LOG_DETAIL]
                ([TRANSACTION_NO]
                ,[TABLE_NAME]
                ,[OPERATION_TYPE]
                ,[DATA_CHANGE])
        SELECT INSERTED.TRANSACTION_NO
                , 'T_ORDER'
                ,'Update'
                ,'<dataChange> <before order_id ="'+CONVERT(VARCHAR,DELETED.ORDER_ID)+'"' +
                ' order_date="' +CONVERT(VARCHAR,DELETED.ORDER_DATE) + '"' +
                ' supplier="'+DELETED.SUPPLIER +'"/>' +
                '<after order_id ="'+CONVERT(VARCHAR,INSERTED.ORDER_ID)+'"' +
                ' order_date="' +CONVERT(VARCHAR,INSERTED.ORDER_DATE) + '"' +
                ' supplier="'+INSERTED.SUPPLIER +'"/></dataChange>'
        FROM DELETED INNER JOIN INSERTED ON
        DELETED.ORDER_ID = INSERTED.ORDER_ID           
        WHERE INSERTED.NEED_AUDIT  = 1    
        
END    

GO

For Delete: tr_order_d

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'tr_order_d')
    BEGIN
        DROP  Trigger tr_order_d
    END
GO

CREATE Trigger tr_order_d ON dbo.T_ORDER 
AFTER DELETE
AS

BEGIN        
        
        INSERT [dbo].[T_AUDIT_LOG_DETAIL]
                ([TRANSACTION_NO]
                ,[TABLE_NAME]
                ,[OPERATION_TYPE]
                ,[DATA_CHANGE])
                
        SELECT TRANSACTION_NO
                , 'T_ORDER'
                ,'Delete'
                ,'<dataChange> <before order_id ="'+CONVERT(VARCHAR,DELETED.ORDER_ID)+'"' +
                ' order_date="' +CONVERT(VARCHAR,DELETED.ORDER_DATE) + '"' +
                ' supplier="'+DELETED.SUPPLIER +'"/></dataChange>' 
        FROM DELETED
END
GO

2. T_ORDER_DETAIL
For Insert: tr_order_detail_i

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = 'sp_order_detail_i')
    BEGIN
        DROP  Procedure  sp_order_detail_i
    END

GO

CREATE Procedure sp_order_detail_i
    (
        @p_order_id INT,
        @p_product_id INT,
        @p_product_name VARCHAR(50),
        @p_unit_price MONEY,
        @p_quantity INT,
        @p_created_by VARCHAR(50),
        @p_created_on DATETIME,
        @p_last_updated_by VARCHAR(50),
        @p_last_updated_on DATETIME,
        @p_transaction_no CHAR(36)        
    )

AS

INSERT INTO [dbo].[T_ORDER_DETAIL]
           ([ORDER_ID]
           ,[PRODUCT_ID]
           ,[PRODUCT_NAME]
           ,[UNIT_PRICE]
           ,[QUANTITY]
           ,[CREATED_BY]
           ,[CREATED_ON]
           ,[LAST_UPDATED_BY]
           ,[LAST_UPDATED_ON]
           ,[TRANSACTION_NO])
     VALUES
           (@p_order_id,
            @p_product_id,
            @p_product_name,
            @p_unit_price,
            @p_quantity,
            @p_created_by ,
            @p_created_on ,
            @p_last_updated_by ,
            @p_last_updated_on ,
            @p_transaction_no)
            
IF @@ROWCOUNT = 0 
BEGIN
    RAISERROR ('Version conflicts!',10,1)
END
GO

For Update: tr_order_detail_u

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'tr_order_detail_u')
    BEGIN
        DROP  Trigger tr_order_detail_u
    END
GO

CREATE Trigger tr_order_detail_u ON dbo.T_ORDER_DETAIL
AFTER UPDATE
AS
IF UPDATE(VERSION_NO)
BEGIN
        INSERT [dbo].[T_AUDIT_LOG_DETAIL]
                ([TRANSACTION_NO]
                ,[TABLE_NAME]
                ,[OPERATION_TYPE]
                ,[DATA_CHANGE])
        SELECT INSERTED.TRANSACTION_NO
                , 'T_ORDER_DETAIL'
                ,'Update'
                ,'<dataChange> <before order_id ="'+CONVERT(VARCHAR,DELETED.ORDER_ID)+'"' +
                ' product_id="' +CONVERT(VARCHAR,DELETED.PRODUCT_ID) + '"' +
                ' product_name="' +CONVERT(VARCHAR,DELETED.PRODUCT_NAME) + '"' +
                ' unit_price="' +CONVERT(VARCHAR,DELETED.UNIT_PRICE) + '"' +
                ' quantity="'+CONVERT(VARCHAR,DELETED.QUANTITY) +'"/>' +
                '<after order_id ="'+CONVERT(VARCHAR,INSERTED.ORDER_ID)+'"' +
                ' product_id="' +CONVERT(VARCHAR,INSERTED.PRODUCT_ID) + '"' +
                ' product_name="' +CONVERT(VARCHAR,INSERTED.PRODUCT_NAME) + '"' +
                ' unit_price="' +CONVERT(VARCHAR,INSERTED.UNIT_PRICE) + '"' +
                ' quantity="'+CONVERT(VARCHAR,INSERTED.QUANTITY) +'"/></dataChange>'
        FROM DELETED INNER JOIN INSERTED ON
        DELETED.ORDER_ID = INSERTED.ORDER_ID          
        AND     DELETED.PRODUCT_ID = INSERTED.PRODUCT_ID      
        WHERE INSERTED.NEED_AUDIT  = 1    

END   

GO

For Delete: tr_order_detail_d

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'TR' AND name = 'tr_order_detail_d')
    BEGIN
        DROP  Trigger tr_order_detail_d
    END
GO

CREATE Trigger tr_order_detail_d ON dbo.T_ORDER_DETAIL
AFTER DELETE
AS        

        INSERT [dbo].[T_AUDIT_LOG_DETAIL]
                ([TRANSACTION_NO]
                ,[TABLE_NAME]
                ,[OPERATION_TYPE]
                ,[DATA_CHANGE])
        SELECT DELETED.TRANSACTION_NO
                , 'T_ORDER_DETAIL'
                ,'Delete'
                ,'<dataChange> <before order_id ="'+CONVERT(VARCHAR,DELETED.ORDER_ID)+'"' +
                ' product_id="' +CONVERT(VARCHAR,DELETED.PRODUCT_ID) + '"' +
                ' product_name="' +CONVERT(VARCHAR,DELETED.PRODUCT_NAME) + '"' +
                ' unit_price="' +CONVERT(VARCHAR,DELETED.UNIT_PRICE) + '"' +
                ' quantity="'+CONVERT(VARCHAR,DELETED.QUANTITY) +'"/></dataChange>'
        FROM DELETED       
GO

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-09-09 17:49:03

Audit Logging: Triggers的相关文章

如何追踪每一笔记录的来龙去脉:一个完整的Audit Logging解决方案[下篇]

通过第一部分的介绍,我们对这个Audit Logging解决方案的原理有了较为全面的了解,接下来我们将通过一个简单的Sample来进一步介绍如何在一个具体的应用中如何实现这样一个Audit Logging. 我们沿用在Part I提出的Order management 场景,为了简单起见,我们通过一个Console application来模拟.在这个Application中,你将会看到如何以一种离线的模式操作数据库,如何Log这些操作. 我们首先来介绍Sample程序的结构(如下图).整个So

Web开发人员编程模型:隔离级别

ACID性质是数据库理论中的奠基石,它定义了一个理论上可靠数据库所必须具备的四个性质:原子性,一致性,隔离性和持久性.虽然这四个性质都很重要,但是隔离性最为灵活.大部分数据库都提供了一些可供选择的隔离级别,且现在许多库都增加了附加层来创建颗粒度更细的隔离.隔离级别应用范围如此之广主要是因为放宽隔离约束往往会使得可扩展性和性能提高几个数量级. 串行一致性是可用的最古老最高的隔离级别之一,它之所以倍受青睐是因为其提供的简单编程模型,即每次仅能有一个事务对给定的资源进行操作,这就避免了很多潜在的资源问

Linux Shell之init脚本与activemq init脚本设计亮点分析

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dgd2010.blog.51cto.com/1539422/1680420 上一篇博文<Linux下Apache ActiveMQ5.9的安装配置与测试>中详细叙述了activemq的安装配置和如何利用java小程序测试activemq是否正常工作.此篇文章将继续剖解activemq中的一些精华内容,从activemq的init脚本说起.init(initialization

PostgreSQL 10.0 preview 功能增强 - 匿名、自治事务(Oracle 兼容性)

标签 PostgreSQL , 10.0 , 匿名事务 , 自治事务 背景 PostgreSQL 10.0 通过session backendground实现了匿名事务,从此可以愉快的支持Oracle存储过程的自治事务了. 此前,我们需要通过dblink实现,或者通过匿名块+exception来实现,比较繁琐. <PostgreSQL Oracle 兼容性之 - plpgsql 自治事务(autonomous_transaction)补丁> <PostgreSQL Oracle 兼容性之

IBM Cognos BI企业级商业智能产品日志简介

IBM Cognos BI 作为一款企业级商业智能产品,正在被更多的客户所接受.同时,IBM Cognos BI 在日志方面也提供了强大的支持,本文将涵盖 IBM Cognos 日志(基础)主题,较为详细的介绍产品所提供的常见类型日志,其中也涵盖了如何利用日志进行诊断.排错等相关内容. IBM Cognos BI 日志简介 本文将以 IBM Cognos BI 10.2.0 作为事例对产品的日志系统做出一个讲解,但同时由于在以前版本也使用了同样的架构,所以本文也可以用于 8.4.1 版本以及 1

Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)

  Acknowledgments I would like to thank Jacob Kjome for reviewing early drafts of this document. His comments helped to clarify several important points. Jake also keeps reminding us on the log4j-dev mailing list that the child-parent delegation mode

黄聪:Microsoft Enterprise Library 5.0 系列教程(四) Logging Application Block

原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(四) Logging Application Block 企业库日志应用程序模块工作原理图:        从上图我们可以看清楚企业库日志应用程序模块的工作原理,其中LogFilter,Trace Source,Trace Listener,Log Formatter的信息都可以在Category配置文件中反映出来,通过配置文件,调用LogWriter类的Writer方法,就可以将包含日志信息的LogEntr

ORA-28056: Writing audit records to Windows Event Log failed

C:\>sqlplus / as sysdba SQL*Plus: Release 11.2.0.1.0 Production on 星期四 1月 5 13:55:44 2012 Copyright (c) 1982, 2010, Oracle.  All rights reserved. ERROR: ORA-28056: Writing audit records to Windows Event Log failed ORA-28056: Writing audit records to

Python中由于logging模块误用导致的内存泄露的解决方法

  Python中由于logging模块误用导致的内存泄露的解决方法         这篇文章主要介绍了解决Python中由于logging模块误用导致的内存泄露,针对由于过多的UDP连接所产生的问题,需要的朋友可以参考下 首先介绍下怎么发现的吧, 线上的项目日志是通过 logging 模块打到 syslog 里, 跑了一段时间后发现 syslog 的 UDP 连接超过了 8W, 没错是 8 W. 主要是 logging 模块用的不对 我们之前有这么一个需求, 就是针对每一个连接日志输出当前连接