在SQL Server中创建数据审核

时间:2011-08-22 16:19:50

标签: sql sql-server audit

我最近被赋予了在数据库表上创建审计的任务,以便可以跟踪对任何列所做的任何更改。

假设我有下表:

[TableA]
------
ID
ColumnA
ColumnB
ColumnC

对于审核,我创建了一个表格,如:

[TableA.Audit]
------
ID
TableAID
UserID
Date (default value = getdate())
ColumnA
ColumnB
ColumnC

然后我写了一个像:

的脚本
DECLARE @currentColumnA int
       ,@currentColumnB int
       ,@currentColumnC int

SELECT TOP 1 @currentColumnA=ColumnA
            ,@currentColumnB=ColumnB
            ,@currentColumnC=ColumnC
FROM [TableA]
WHERE ID=@TableAID

UPDATE [TableA]
SET ColumnA=@ColumnA
    ,ColumnB=@ColumnB
    ,ColumnC=@ColumnC
WHERE ID=@TableAID

INSERT INTO [TableA.Audit] (TableAID, UserID, ColumnA, ColumnB, ColumnC)
VALUES (@TableAID, @UserID, NULLIF(@ColumnA, @currentColumnA), NULLIF(@ColumnB, @currentColumnB), NULLIF(@ColumnC, @currentColumnC))

问题在于,如果我要向ColumnD添加TableA字段,我将不得不编辑我的TableA.Audit表以及上述脚本。

因此有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

最好为AFTER INSERT,AFTER DELETE和AFTER UPDATE之后的表编写触发器。这样,只要在表中插入,更新或删除数据,ANYTHING(应用程序,Management Studio等)就会被记录。您必须为审核操作添加一个字段,并在触发器中插入操作的文字(例如“I”或“INSERT”)。我以这种方式构建我的审计表:

audit_id: INT IDENTITY 
audit_date: DATETIME GETDATE() 
audit_action: VARCHAR(16) ... or you can use CHAR(1) 
audit_user: VARCHAR(128) SUSER_SNAME()
(the fields from the table being audited)

由于我们的应用程序使用Active Directory,因此我可以将audit_user默认为SUSER_SNAME()。

答案 1 :(得分:1)

我们使用触发器(唯一的方法去确保你编写它们来处理多个记录插入/更新/删除),我们的结构有点不同。 首先,我们有一个表,用于存储有关操作的信息,人员/应用程序,它是受影响记录的日期数量。然后我们有一个存储细节的表。此表具有标识符列,column_name,旧值,新值。 (我们对审计表中的列使用nvarchar(max))这样,如果表获取新列,我们不必担心更改审计表。我们审计的每个表都有一组审计表。

较新版本的Sql server具有更改跟踪功能,但我们发现它没有足够的详细信息用于我们需要的审核,除非您将数据移动到另一个永久表,否则它会过快删除数据。

答案 2 :(得分:0)

  

问题在于,如果我要添加ColumnD字段   TableA我将不得不编辑我的TableA.Audit表以及   上面的剧本。

     

因此有更好的方法吗?

不是真的。您可以通过触发器更好地实现实现,如HardCode所提到的那样,但您仍然需要修改审计和相关的scirpts。

我目睹了在不必更新触发器或审计表的情况下尝试使其“更好”。对于更大的问题,这总是导致交易小问题(嘿,一个专栏已经添加,我必须做一些事情)。通常是性能,正确性和可靠性问题。