触发器
触发器定义一组操作,在响应对指定表的插入、更新或删除操作时将执行这些操作。执行这样的 SQL 操作时,触发器被认为是已激活的。触发器是可选的,并且可使用 CREATE TRIGGER 语句定义。
可将触发器与引用约束和检查约束配合使用,以强制执行数据完整性规则。还可使用触发器来导致更新其他表、自动生成或变换插入或更新的行的值或者调用函数以执行如发出警报之类的任务。
对于定义或强制事务性业务规则,触发器是非常有用的机制,这些规则涉及数据的不同状态(例如,薪水增长不能超过 10%)。
使用触发器会设置逻辑以在数据库内强制使用业务规则。这表示应用程序不负责强制使用这些规则。对所有表强制使用的集中逻辑意味着更容易维护,因为在逻辑更改时,不需要更改应用程序。
下列各项是在创建触发器时指定的:
- 主题表指定对其定义触发器的表。
- 触发事件定义修改主题表的特定 SQL 操作。该事件可以是插入、更新或删除操作。
- 触发器激活时间指定触发器应在触发事件发生之前还是之后激活。
导致触发器激活的语句包括一组受影响的行。这些行就是正对其进行插入、更新或删除操作的主题表的行。触发器粒度指定触发器的操作是对该语句执行一次,还是对每个受影响的行执行一次。
触发操作包括可选搜索条件和每次激活触发器时执行的一组语句。仅当搜索条件求值为 true 时,才执行这些语句。如果触发器激活时间是在触发器事件之前,那么触发操作可包括用于进行选择、设置转换变量或发信号表明 SQL 状态的语句。如果触发器激活时间是在触发器事件之后,那么触发操作可包括用于进行选择、插入、更新、删除或发信号表明 SQL 状态的语句。
触发操作可使用转换变量来引用一组受影响的行中的值。转换变量使用由指定的名称限定的主题表中的各个列名,以标识是引用旧值(更新前)还是引用新值(更新后)。在之前、插入或更新触发器中,还可使用 SET Variable 语句来更改新值。
引用一组受影响的行中的各个值的另一种方法是使用转换表。转换表同样使用主题表中的各个列名,但它指定一个名称,以允许将一整组受影响的行视作一个表。只能在后触发器中使用转换表(也就是说,不能在前触发器和 INSTEAD OF 触发器中使用),并且可以对旧值和新值定义单独的转换表。
可以对表、事件(INSERT、UPDATE 和 DELETE)或激活时间(BEFORE、AFTER 和 INSTEAD OF)的组合指定多个触发器。当对特定表、事件和激活时间存在多个触发器时,激活触发器的顺序与创建它们的顺序相同。因此,最新创建的触发器就是最后激活的触发器。
激活触发器可能导致触发器级联,这是由于激活了一个执行语句的触发器,这些语句导致激活其他触发器或再次激活相同触发器。触发操作还可能导致对删除操作应用引用完整性规则而产生的更新,从而可能导致激活更多触发器。借助触发器级联,可能会激活触发器和引用完整性删除规则链,从而由于单个 INSERT、UPDATE 或 DELETE 语句而导致对数据库的大幅度更改。
当多个触发器对同一对象执行插入、更新或删除操作时,会使用冲突解决机制(如临时表)来解决访问冲突。这样可能会对性能产生显著影响,在分区数据库环境中尤其如此。