跟踪对数据库行的更改(SQL Server)

时间:2011-02-02 17:34:56

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

  

可能重复:
  Auditing SQL Server data changes

我的要求是要求在数据库中插入和更新的每一行,以跟踪进行更改的人(创建者/修饰符),创建记录的时间以及修改记录的时间。我在所有表中都有行ID的guid,所以我想我会想出一个表rowdata

rowdatacreated (datetime)modified (datetime)createdby(字符串或用户ID),modifiedbysummary列(字符串,摘要)变化)

然后放置一些插入/更新触发器。你觉得还不错还是有另外一个wa(可能是开箱即用的)?

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

2 个答案:

答案 0 :(得分:4)

触发器确实是以这种方式审核表的头号选项。

答案 1 :(得分:3)

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

[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()函数非常有用,因为我们在app和windows身份验证中使用模拟来连接数据库。这可能不适用于您的情况。