Sql server 审核触发器中插入的每一行

Sql server 审核触发器中插入的每一行,sql-server,triggers,Sql Server,Triggers,我试图通过向表中添加触发器并向审核表中插入行来创建审核历史记录。我有一个存储过程,它使插入变得更容易,因为它可以保存代码;我不必写出整个insert语句,而是使用要插入的列的一些参数来执行存储过程 我不知道如何为插入表中的每一行执行存储过程。我想也许我需要使用光标,但我不确定。我以前从未使用过光标 因为这是一个审计,我需要比较每一列新旧的值,看看它是否改变了。如果它确实发生了更改,我将执行将行添加到审计表的存储过程 有什么想法吗?如果您的数据库需要扩展到超过几个用户,这将非常昂贵。我建议您研究第

我试图通过向表中添加触发器并向审核表中插入行来创建审核历史记录。我有一个存储过程,它使插入变得更容易,因为它可以保存代码;我不必写出整个insert语句,而是使用要插入的列的一些参数来执行存储过程

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

因为这是一个审计,我需要比较每一列新旧的值,看看它是否改变了。如果它确实发生了更改,我将执行将行添加到审计表的存储过程


有什么想法吗?

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

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

我会以空间换取时间,而不会进行比较。插入/更新时,只需将新值推送到审核表。磁盘很便宜

另外,我不确定存储过程为您带来了什么。你不能在触发器中执行一些简单的操作,比如:

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)
此外,您是否计划只审核成功或失败?如果你想审核失败,你需要一些触发器以外的东西,因为如果事务回滚,触发器就不会运行——如果触发器先运行,你就没有事务的状态


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

我会用空间换取时间,而不会进行比较。插入/更新时,只需将新值推送到审核表。磁盘很便宜

另外,我不确定存储过程为您带来了什么。你不能在触发器中执行一些简单的操作,比如:

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)
此外,您是否计划只审核成功或失败?如果你想审核失败,你需要一些触发器以外的东西,因为如果事务回滚,触发器就不会运行——如果触发器先运行,你就没有事务的状态


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

已经有一个内置函数更新,它告诉您一列是否已更改,但它覆盖了整个插入行集

您可以查看一些生成代码的技术

它所做的是同时检查:

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)

但它将每一列更改作为单独的行进行审核。我使用它来审核配置表的更改。我目前没有将其用于审核大量更改表。但在我设计的大多数事务系统中,重活动表上的行通常是不可变的,您没有太多的更新,只有太多的插入-因此您甚至不需要这种审计。例如,订单或分类账条目永远不会更改,购物车是一次性的——两者都不会有这种审计。在低容量更改表(如customer)上,您可以使用这种审核。

已经有一个内置函数更新,它会告诉您某个列是否已更改,但它已覆盖整个插入行集

您可以查看一些生成代码的技术

它所做的是同时检查:

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)
但它将每一列更改作为单独的行进行审核。我使用它来审核配置表的更改。我目前没有将其用于审核大量更改表。但在我设计的大多数事务系统中,重活动表上的行通常是不可变的,您没有太多的更新,只有太多的插入-因此您甚至不需要这种审计。F 例如,订单或分类账条目永远不会更改,购物车是一次性的——两者都不会有这种审计。在诸如customer之类的低容量更改表上,您可以使用这种审计。

Jeff, 我同意Zodeus…一个好的选择是使用第三个工具。 我使用了auditdatabase FREEweb工具,它可以生成审计触发器,您不需要编写一行TSQL代码

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

我希望这对你有帮助, F.奥尼尔

杰夫, 我同意Zodeus…一个好的选择是使用第三个工具。 我使用了auditdatabase FREEweb工具,它可以生成审计触发器,您不需要编写一行TSQL代码

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

我希望这对你有帮助,
F.奥尼尔

我同意。磁盘很便宜。每次只需保存新插入的值。旧值将在审计表的前一行。我同意。磁盘很便宜。每次只需保存新插入的值。旧值将位于审核表的前一行。您使用的SQL Server版本是什么?如果SQL 2K8中有一些内置的审计工具,它们必须比您正在构建的工具更易于维护。您使用的是什么版本的SQL Server?如果SQL 2K8中有一些内置的审计工具,它们必须比您正在构建的工具更易于维护。站点是www.auditdatabase.com站点是www.auditdatabase.com