2011-02-02 44 views
2

可能重复:
Auditing SQL Server data changes跟踪数据库更改的行(SQL Server)的

我要求插入和更新数据库中的每一行跟踪谁进行了更改需求(创造者/修饰语),创建记录和修改记录时。我对所有表中的行ID的GUID,所以我想我会拿出一张桌子rowdata

rowdata:变化的created (datetime)modified (datetime)createdby(字符串或用户ID),modifiedby也许summary列(字符串,汇总)

然后放置一些插入/更新触发器。你认为是好还是有另一个洼(也许是开箱即用的)?

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

+0

使用SQL Server 2008审计功能 - 查看重复的问题和答案 – 2011-02-02 17:38:52

回答

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 

以及更新触发器如下所示:

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身份验证中使用模拟来连接到数据库。这可能不适用于你的情况。

4

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