【发布时间】:2021-09-23 09:02:51
【问题描述】:
如果我有如下陈述。
Update table emp set sal=10 where 1=2
我已经应用了所有四个触发器:
- 以前,
- 之后,
- 语句级别,
- 行级
那么哪些触发器会被触发?
提前致谢!!
【问题讨论】:
如果我有如下陈述。
Update table emp set sal=10 where 1=2
我已经应用了所有四个触发器:
那么哪些触发器会被触发?
提前致谢!!
【问题讨论】:
你为什么不测试一下?
SQL> create table test as select empno, sal from emp where deptno = 10;
Table created.
SQL> create or replace trigger trg_bu_r
2 before update on test
3 for each row
4 begin
5 dbms_output.put_line('Before row');
6 end;
7 /
Trigger created.
SQL> create or replace trigger trg_au_r
2 after update on test
3 for each row
4 begin
5 dbms_output.put_line('After row');
6 end;
7 /
Trigger created.
SQL> create or replace trigger trg_bu_s
2 before update on test
3 begin
4 dbms_output.put_line('Before statement');
5 end;
6 /
Trigger created.
SQL> create or replace trigger trg_au_s
2 after update on test
3 begin
4 dbms_output.put_line('After statement');
5 end;
6 /
Trigger created.
SQL> set serveroutput on
SQL> update test set sal = 10 where 1 = 2;
Before statement
After statement
0 rows updated.
SQL>
【讨论】:
您可以使用 sp_settriggerorder 定义表上每个触发器的顺序。 SQL Server triggers - order of execution
【讨论】:
将触发哪些触发器?
所有相关触发器都会触发,除非引发异常并终止更新。您的语句将更新零行(因为 1=2 过滤器)。 语句仍在执行,因此语句级触发器将触发;但由于没有行受到影响,因此不会触发行级触发器。
一个简单的 DML 触发器恰好在以下时间点之一触发:
- 在触发语句运行之前...
- 触发语句运行后...
- 在触发语句影响的每一行之前...
- 在触发语句影响的每一行之后...
注意行级触发器的“触发语句影响的每一行”部分。如果触发语句不影响任何行,则它们不会触发。
他们发射的顺序也很重要,这也显示在in the documentation:
如果为同一张表上的同一个语句定义了两个或多个具有不同时间点的触发器,则它们按以下顺序触发:
- 所有
BEFORE STATEMENT触发器- 所有
BEFORE EACH ROW触发器- 所有
AFTER EACH ROW触发器- 所有
AFTER STATEMENT触发器
您可以see that in action,使用@Littlefoot 代码的修改版本,更新零行、单行和多行。
文档中有更多建议超出了您的具体问题,但您可能会在某些时候发现相关或有用:
如果可行,请将具有不同时间点的单个触发器集合替换为单个复合触发器,该触发器按您想要的顺序显式编码操作。有关复合触发器的信息,请参阅“Compound DML Triggers”。
如果您要创建两个或多个具有相同时间点的触发器,并且它们的触发顺序很重要,那么您可以使用
FOLLOWS和PRECEDES子句控制它们的触发顺序(请参阅“FOLLOWS | PRECEDES ")。
【讨论】: