2

可能重复:
审核 SQL Server 数据更改

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

rowdata: created (datetime), modified (datetime), createdby(字符串或用户 ID),modifiedby也许还有summary列(字符串,更改摘要)

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

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

4

2 回答 2

4

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

于 2011-02-02T17:38:44.970 回答
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() 函数很有用,因为我们在应用程序中使用模拟和 Windows 身份验证来连接数据库。这可能不适用于您的情况。

于 2011-02-02T18:00:04.390 回答