【问题标题】:AUDIT TRAIL OF TABLES表的审计跟踪
【发布时间】:2018-01-31 12:44:46
【问题描述】:

我想对特定表进行审计跟踪,例如 表中插入、更新、删除的内容以及所有这些日志都保存在一个表中 我正在使用 sql server 2012 。 任何人都可以帮助我如何实现这一目标?

请注意 - 光标的使用受到限制

【问题讨论】:

    标签: sql sql-server tsql audit


    【解决方案1】:

    在该表上创建一个后触发器并将记录插入到日志表中。

    create trigger <trigger_name> after insert/update/delete/ on 
    table <orig table>
      begin
         insert into the log tables ('all the fields that you require');
      end 
    

    【讨论】:

      【解决方案2】:

      尝试使用CDC (Change Data Capture)。一个非常有用的工具,有助于管理审计跟踪

      阅读来自MSDN的文章

      【讨论】:

        【解决方案3】:

        这可以使用Triggers 来实现。如果在您的表上发生大型插入、删除和更新操作,触发器将使您的 DML 操作变慢。如果是小表,您可以创建如下所示的 TRIGGER,以根据发生的操作将行记录到另一个表中。

        您可以使用Inserted and Deleted 魔术表来保存触发器内正在插入和删除的行。

        如果您需要使用 CDC (Change Data Capture) 对审计进行更多控制,还有另一种选择。

        CREATE TABLE TrailTable
        (
            Id INT,
            Name VARCHAR(100)
        );
        
        CREATE TABLE TrailTableLog
        (
            Id INT,
            Name VARCHAR(100),
            Action CHAR(3)
        );
        
        
        Insert Into TrailTable VALUES (1,'Vi');
        Insert Into TrailTable VALUES (2,'Vr');
        Insert Into TrailTable VALUES (3,'An');
        Insert Into TrailTable VALUES (4,'Ma');
        
        CREATE TRIGGER dbo.TRG_IDU_TrailTable
        ON dbo.TrailTable
        AFTER INSERT, UPDATE, DELETE
        AS 
        BEGIN
            SET NOCOUNT ON;
        
            DECLARE @Action as char(1);
            SET @Action = (CASE WHEN EXISTS(SELECT * FROM INSERTED)
                                 AND EXISTS(SELECT * FROM DELETED)
                                THEN 'U'  -- Set Action to Updated.
                                WHEN EXISTS(SELECT * FROM INSERTED)
                                THEN 'I'  -- Set Action to Insert.
                                WHEN EXISTS(SELECT * FROM DELETED)
                                THEN 'D'  -- Set Action to Deleted.
                                ELSE NULL -- Skip. It may have been a "failed delete".   
                            END)
        
            IF(@Action = 'I')
            BEGIN
                INSERT INTO TRG_IDU_TrailTable (Id, Name, Action)
                SELECT Id, Name, 'I' FROM INSERTED;
            END
        
            IF(@Action = 'D')
            BEGIN
                INSERT INTO TRG_IDU_TrailTable (Id, Name, Action)
                SELECT Id, Name, 'D' FROM DELETED;
            END
        
            IF(@Action = 'U')
            BEGIN
        
                INSERT INTO TRG_IDU_TrailTable (Id, Name, Action)
                SELECT Id, Name, 'U-D' FROM INSERTED; -- Records Deleted to Update
        
                INSERT INTO TRG_IDU_TrailTable (Id, Name, Action)
                SELECT Id, Name, 'U-I' FROM INSERTED; --Records Inserted to Update
            END
        
        END
        

        【讨论】:

        • 不要带触发器,会导致死锁。
        • @TripurariYadav 您能否通过示例阐明您的陈述,并提出一个不会导致死锁的替代方案。死锁不仅可能因为触发器而发生,如果数据库设计正确,并且代码没有编写,它也可能发生在存储过程中。
        • @mr_eclair 触发器非常昂贵,所以不要这样做。相反,您可以使用过程。您可以在添加、更新删除记录时通过应用程序级别进行日志输入。您可能有一个插入数据的过程,在该过程中,您可以将数据添加到日志表中。
        • example --Insert in main table Insert into CityMaster(CityName)values('Mumbai') --Insert in log table Insert into log_CityMaster(CityName)values('Mumbai')
        猜你喜欢
        • 1970-01-01
        • 2011-11-26
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        • 1970-01-01
        • 2023-03-18
        • 2018-10-23
        • 1970-01-01
        相关资源
        最近更新 更多