Bra*_*ann 0 trigger sql-server sql-server-2008-r2
我有一个非常基本的触发器定义如下:
CREATE TRIGGER dbo.foo
ON dbo.bar
FOR INSERT, UPDATE, DELETE
AS
...
Run Code Online (Sandbox Code Playgroud)
我还有一个存储过程,它在某些时候会做这样的事情:
Insert into dbo.bar (a) select a from @bar
Run Code Online (Sandbox Code Playgroud)
当@bar 包含一些数据时,我的触发器会按预期调用,但当它不包含时,即使 dbo.bar 显然没有更改,也会调用触发器。
SQL 探查器和 sys.dm_exec_trigger_stats 的内容都证实了这一点。
SQL Profiler 报告占用空间非常低(3 次读取,0 次写入),但由于我有很多触发器,因此这种情况经常发生,并且最终得到了重要的 total_reads 数字。
关于为什么会发生这种情况的任何提示?有没有办法改变这种行为?
这是语句触发器的预期行为。每次执行一条语句(INSERT在本例中)和一次(每条语句,而不是每行)时,它都会执行一次。其他 DBMS(如 Oracle)中的行为类似。
MSDN 在CREATE TRIGGER页面的第一段中说:
无论是否有任何表行受到影响,当触发任何有效事件时都会触发这些触发器。
我认为没有办法改变这一点。有一些方法可以检查 - 在触发器内部,一旦触发 - 是否有受影响的行并相应地采取行动。
例如,您可以使用
IF ( @@ROWCOUNT = 0 )
RETURN;
Run Code Online (Sandbox Code Playgroud)
或者在存在的情况下更强大的替代方案MERGE
IF NOT EXISTS(SELECT *
FROM DELETED)
AND NOT EXISTS(SELECT *
FROM INSERTED)
RETURN;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
75 次 |
| 最近记录: |