【问题标题】:Tracking changes to database rows (SQL Server) [duplicate]跟踪对数据库行的更改(SQL Server)[重复]
【发布时间】:2011-02-02 17:34:55
【问题描述】:

可能重复:
Auditing SQL Server data changes

我的需求要求对数据库中插入和更新的每一行进行跟踪,以跟踪谁进行了更改(创建者/修改者)、记录的创建时间和修改时间。我在所有表中都有行 ID 的指南,所以我想我会想出一个表 rowdata

rowdatacreated (datetime)modified (datetime)createdby(字符串或用户 ID)、modifiedby 可能还有 summary 列(字符串,更改摘要)

然后放置一些插入/更新触发器。你认为这很好还是有另一种方式(可能是开箱即用的方式)?

我的开发环境是 .NET 4,所以如果您想到其他可能会遇到问题的选项,请告知。

【问题讨论】:

  • 使用 SQL Server 2008 审计功能 - 查看重复的问题和答案

标签: .net sql sql-server .net-4.0 change-tracking


【解决方案1】:

触发器确实是以这种方式审计表的第一选择。

【讨论】:

    【解决方案2】:

    我有类似的要求,但通过将这四列添加到需要跟踪审计的所有表中:

    [Create_User] [nvarchar](100) NULL,
    [Create_Date] [datetimeoffset](7) NULL,
    [Modify_User] [nvarchar](100) NULL,
    [Modify_Date] [datetimeoffset](7) NULL,
    

    INSERT 触发器如下所示:

    CREATE TRIGGER [SomeSchema].[Some_Table_Insert_Create] ON [SomeSchema].[Some_Table] FOR INSERT AS 
       SET NOCOUNT ON
    
       IF EXISTS(SELECT * FROM INSERTED WHERE Create_User IS NOT NULL)
          BEGIN   
             UPDATE [SomeSchema].[Some_Table] SET 
                Create_Date = SYSDATETIMEOFFSET()
             FROM 
                [SomeSchema].[Some_Table]
             INNER JOIN 
                INSERTED 
             ON 
                [SomeSchema].[Some_Table].Some_Table_Id = INSERTED.Some_Table_Id
          END
       ELSE
          BEGIN
             UPDATE [SomeSchema].[Some_Table] SET 
                Create_User = SUSER_SNAME(),
                Create_Date = SYSDATETIMEOFFSET()
             FROM 
                [SomeSchema].[Some_Table]
             INNER JOIN 
                INSERTED 
             ON 
                [SomeSchema].[Some_Table].Some_Table_Id = INSERTED.Some_Table_Id
          END
    

    UPDATE 触发器如下所示:

    CREATE TRIGGER [SomeSchema].[Some_Table_Update_Modify] ON [SomeSchema].[Some_Table] FOR UPDATE AS 
    
       SET NOCOUNT ON
    
       IF NOT UPDATE (Create_User) AND NOT UPDATE (Create_Date)
          BEGIN
             IF EXISTS(SELECT * FROM INSERTED WHERE Modify_User IS NOT NULL)
                 BEGIN  
                     UPDATE [SomeSchema].[Some_Table] SET 
                         Modify_Date = SYSDATETIMEOFFSET()
                     FROM 
                         [SomeSchema].[Some_Table]
                     INNER JOIN 
                         INSERTED 
                     ON 
                         [SomeSchema].[Some_Table].Some_Table_Id = INSERTED.Some_Table_Id
                 END
             ELSE
                 BEGIN
                     UPDATE [SomeSchema].[Some_Table] SET 
                         Modify_User = SUSER_SNAME(),
                         Modify_Date = SYSDATETIMEOFFSET() 
                     FROM 
                         [SomeSchema].[Some_Table]
                     INNER JOIN 
                         INSERTED 
                     ON 
                         [SomeSchema].[Some_Table].Some_Table_Id = INSERTED.Some_Table_Id
                 END
          END
    

    SUSER_SNAME() 函数很有用,因为我们在应用程序中使用模拟和 Windows 身份验证来连接数据库。这可能不适用于您的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多