SQL: 语句触发器 VS 每行触发器

7

编辑:我不知道这是哪个发行版,因为它出现在一份考试试卷中。

很遗憾,我没有理解这个问题。我对行级触发器感到满意,但是能否有人向我解释一下如果触发器是语句级别的,结果会有什么不同呢?

关系/语句触发器/行级触发器

Employee(ID VARCHAR2(30), Salary NUMBER)


Create Trigger AutoRaise
After insert on Employee
Referencing new table as NT
update Employee
Set salary = salary + (select avg(salary) from NT)


Create trigger AutoRaise
After insert on Employee
Referencing new table as NT
For each Row
Update employee
Set salary = salary + (select avg(salary) from NT)

我知道在“for each row”触发器中,它会为触发语句所影响的每一行都触发。那么语句级触发器是否会以不同方式修改结果呢?比如说,如果我在一个语句中插入了五个元组,那么它们的工资等信息是否都会被设置?如果是这样,那么行级触发器的好处在哪里呢?
我已经尝试搜索,但就是无法理解。
谢谢,
编辑:现在,我可能有点迟钝,但是这两个触发器是否会产生不同的输出结果呢?对于语句级触发器,如果我使用以下示例值:
在触发器创建之前的表中:
(A,50)

在触发器创建后添加一个语句:

(B,70), (C,30)

第一个触发器会为每个要插入的元组设置工资,对吗?那么第一个将变成120(因为平均数是50,70 + 50 = 120),第二个将变成80。如果这是正确的,那么第二个触发器的结果有何不同?

2
你在谈论什么数据库系统以及哪个版本?SQL只是结构化查询语言,许多数据库系统都使用它,但SQL并不是一个数据库产品...这类东西通常是供应商特定的,因此我们真的需要知道你所说的数据库系统是什么。 - marc_s
VARCHAR2 似乎表明它是 Oracle。但是语法无效,因为没有“referencing new table as...”这样的东西,而且也缺少了 begin/end。 - user330315
很遗憾,这是来自过去的考试试卷,没有提到具体的发行版。 - Mo Moosa
DB2δΦΦδΙéφî·φ¨¹REFERENCINGδΫçψIJ - Andriy M
1个回答

4
在语句级触发器中,SELECT avg(salary) FROM NT 返回的是插入行的工资平均值,但在行级触发器中,avg(salary) 总是等于新记录的 salary(对每行分别执行触发器)。此外,如果未影响任何记录,则会执行语句级触发器。在行级触发器中,大多数 RDMS 在未影响 0 条记录时不会触发它。
附注:我认为问题中给出的触发器体仅供参考;否则,即使特定的 RDMS 具有这样的选项,我也建议不要在触发器中使用递归。

嗨,谢谢回复。现在,我可能有点迟钝,但是两个触发器会产生不同的输出吗?对于语句级触发器,如果我使用以下示例值:在触发器创建之前的表中:(A,50)在触发器创建后的一个语句中添加:(B,70), (C,30)第一个触发器将为插入的每个元组设置工资,对吧?所以第一个将变成120(因为平均值为50,70 + 50 = 120),第二个将变成80。如果这是真的,第二个触发器的结果有什么不同呢? - Mo Moosa
1
对于第二个触发器(行级别),情况将会有所不同:插入第一行(B,70):70 + avg(70)= 140。插入第二行(30):第一行(140 + 30)= 170,第二行30 + 30 = 60。行触发器将被执行两次,对于每一行,“NEW_TABLE”将有1条记录。 - a1ex07
此外,如果是行级触发器,很可能会出现错误(或者需要添加一些逻辑来处理递归级别,如果RDMS允许在触发器中进行递归),因为它试图修改同一张表。 - a1ex07
一些数据库如SQL Server没有行级触发器,因为它们是个糟糕的想法。 - HLGEM
如果您使用递归,一次更新太多行可能会导致问题。 - HLGEM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接