审核Trigger中的每个插入行

时间:2009-03-02 19:46:57

标签: sql-server triggers

我正在尝试通过向我的表添加触发器并将行插入到Audit表中来执行审计历史记录。我有一个存储过程,使插入更容易,因为它节省了代码;我不必写出整个insert语句,而是使用我要插入的列的一些参数来执行存储过程。

我不确定如何为“inserted”表中的每一行执行存储过程。我想也许我需要使用光标,但我不确定。我以前从未使用过光标。

由于这是一次审核,因此我需要将每个旧列的值与新值进行比较,以查看它是否发生了变化。如果它确实发生了变化,我将执行向Audit表添加一行的存储过程。

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

我会花时间换空间而不做比较。只需在插入/更新时将新值推送到审计表。磁盘很便宜。

另外,我不确定存储过程会为您带来什么。你不能在触发器中做一些简单的事情,如:

insert into dbo.mytable_audit
    (select *, getdate(), getdate(), 'create' from inserted)

触发器在insert上运行,并且您要添加创建时间,上次更新时间和修改类型字段。对于更新,由于您不需要更新创建的时间,因此您需要提供命名参数,这是一个小问题

insert into dbo.mytable_audit (col1, col2, ...., last_updated, modification)
     (select *, getdate(), 'update' from inserted)

另外,您是否计划仅审核成功或失败?如果你想审计失败,你需要的东西不是我认为的触发器,因为如果事务被回滚,触发器将不会运行 - 如果触发器首先运行,你就不会拥有事务的状态。 / p>

我实际上已将审核移至数据访问层并立即在代码中执行。它使成功和失败审计变得更容易,并且(使用反射)很容易将字段复制到审计对象。它允许我做的另一件事是给用户上下文,因为我没有给数据库的实际用户权限,并使用服务帐户运行所有查询。

答案 1 :(得分:1)

如果您的数据库需要扩展到几个用户,这将变得非常昂贵。我建议查看第三方数据库审计工具。

答案 2 :(得分:1)

已经有一个内置函数UPDATE(),它告诉您列是否已更改(但它是在整个插入行集上)。

您可以查看代码生成的Paul Nielsen's AutoAudit triggers中的一些技术。

它的作用是检查两者:

IF UPDATE(<column_name>)
INSERT Audit (...)
SELECT ...
FROM Inserted
JOIN Deleted
    ON Inserted.KeyField = Deleted.KeyField -- (AutoAudit does not support multi-column primary keys, but the technique can be done manually)
AND NOT (Inserted.<column_name> = Deleted.<column_name> OR COALESCE(Inserted.<column_name>, Deleted.<column_name>) IS NULL)

但它会将每个列更改作为单独的行进行审核。我用它来审核配置表的更改。我目前没有使用它来审核重型更改表。 (但在我设计的大多数事务系统中,重活动表上的行通常是不可变的,你没有很多UPDATE s,只有很多INSERT s - 所以你不会'甚至需要这种审计)。例如,订单或分类帐条目永远不会更改,购物车是一次性的 - 也不会进行此类审核。在小批量变更表(如客户)上,您可以使用此类审计。

答案 3 :(得分:1)

杰夫, 我赞同Zodeus ..一个很好的选择是使用第三个工具。 我使用了auditdatabase(FREE)web工具来生成审计触发器(你不需要编写一行TSQL代码)

另一个好的工具是Apex SQL Audit但是......它不是免费的。

我希望这可以帮到你, F.奥尼尔