【发布时间】:2011-02-19 13:00:04
【问题描述】:
我继承了一个 SQL Server 2008 数据库,调用应用程序可以通过存储过程访问该数据库。
数据库中的每个表都有一个影子审计表,其中记录了插入/更新/删除操作。
对填充审计表的性能测试表明,使用OUTPUT 子句插入审计记录比使用触发器快 20% 左右,因此这已在存储过程中实现。
但是,由于这种设计无法跟踪通过直接针对表发出的 DML 语句直接对表所做的更改,因此还实现了触发器,它使用 @@NESTLEVEL 的值来确定是否运行触发器(假设因为所有通过存储过程运行的 DML 都将具有@@NESTLEVEL > 1)。
即触发代码的主体看起来像:
IF @@NESTLEVEL = 1 -- implies call is direct sql so generate history from here
BEGIN
... insert into audit table
这种设计是有缺陷的,因为它不会跟踪在动态 SQL 中执行 DML 语句的更新,或者@@NESTLEVEL 高于 1 的任何其他上下文。
谁能建议一个完全可靠的方法,我们可以在触发器中使用,仅当不是由存储过程触发时才执行它们?
或者这(我怀疑)不可能?
【问题讨论】:
标签: sql-server sql-server-2008