【问题标题】:Create Data Audit in SQL Server在 SQL Server 中创建数据审计
【发布时间】:2011-11-01 07:13:31
【问题描述】:

我最近接到了一项任务,即在数据库表上创建审计,以便跟踪对任何列所做的任何更改。

假设我有下表:

[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))

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

那么有没有更好的方法呢?

【问题讨论】:

  • 根据您的情况,this answer 可能会有所帮助。 (这是@HLGEM 所说的简化版本。)

标签: sql sql-server audit


【解决方案1】:

您最好为 AFTER INSERT、AFTER DELETE 和 AFTER UPDATE 的表编写触发器。这样,任何插入、更新或删除表中数据的任何时间(应用程序、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()。

【讨论】:

  • 我使用 ASP.NET 表单身份验证/成员资格。无论如何在触发器中获取用户ID?目前我从应用程序传递一个@UserID 参数
  • 您对我如何使用表单身份验证/会员资格有什么建议吗?
  • 我不确定 Membership - 我从未使用过它 - 但对于非 Active Directory 解决方案,您必须将用户 ID 作为常规旧参数传递给存储过程。
  • 要使用表单身份验证,您可以将应用程序的 UserID 放入连接字符串中。例如,我的应用程序称为 SGA。在连接字符串中包含“;Application Name=SGA User MyUserName”。然后您可以使用 T-SQL 的 APP_NAME() 函数并从中取出用户名。
【解决方案2】:

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

较新版本的 Sql server 具有更改跟踪功能,但我们发现它没有足够的详细信息来进行我们需要的审计,并且它会太快地删除数据,除非您将其移动到另一个永久表中。

【讨论】:

    【解决方案3】:

    这个问题是,如果我要添加一个 ColumnD 字段到 TableA 我将不得不编辑我的 TableA.Audit 表以及 上面的脚本。

    那么有没有更好的方法呢?

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

    我目睹了在您不必更新触发器或审计表的情况下使这种“更好”的尝试。这总是导致将小问题(嘿,添加了一个列,我必须做一些事情)换成更大的问题。通常是性能、正确性和可靠性问题。

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 2017-04-12
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多