触发器和参照约束之间的相互作用

创建触发器时,需要了解表中的触发器和约束之间的相互作用。 您还需要了解这些约束和触发器的处理顺序对结果的影响。

一般来说,当触发SQL语句时, S1 会对表执行插入、更新或删除操作,具体步骤如下 T1:
  1. Db2 确定要修改的 行。 T1 把那一排称为 M1。 M1 的内容取决于SQL操作:
    • 对于删除操作,所有满足所搜索删除操作的语句搜索条件或定位删除操作的当前行的行
    • 对于插入操作,VALUES语句标识的行,或INSERT语句中SELECT子句的结果表标识的行
    • 对于更新操作,所有满足更新操作语句搜索条件的行,或定位更新操作中的当前行
  2. Db2 在 上定义的触发器之前,按创建顺序处理所有内容。 T1

    每个触发器在 M1 中为每一行执行一次触发操作。 如果 M1 为空,则不会执行触发操作。

    如果触发操作执行时发生错误, Db2 会回滚 S1 进行的全部更改。

  3. Db2 将语句 中的更改应用到表 ,除非为该操作定义了INSTEAD OF触发器。 S1 T1 如果定义了适当的代替触发器,则 Db2 将执行触发器,而不是语句,并跳过此列表中的剩余步骤。

    如果发生错误, Db2 会回滚 S1 进行的全部更改。

  4. 如果 M1 不为空,则 Db2 将应用以下约束和检查,这些约束和检查在表 T1:
    • 引用约束
    • 检查约束
    • 通过带有检查选项的视图检查表的更新

    在删除触发器或相关表的更新触发器之前,将激活引用约束与DELETE CASCADE或DELETE SET NULL规则的应用。

    如果违反任何约束, Db2 会回滚约束操作或语句 S1 进行的所有更改。

  5. Db2 处理所有在 上定义的触发器,以及所有因参照约束操作而修改的表上的触发器,按创建顺序排列。 T1

    每行触发器对 M1 中的每一行执行一次触发操作。 如果 M1 为空,则不会执行触发操作。

    每次语句后触发器都会在每次执行 S1 时执行一次触发操作,即使 M1 为空。

如果任何触发的操作包含SQL插入、更新或删除操作, Db2 会针对每个操作重复步骤1至5。

若触发操作执行时发生错误,或触发操作处于第17级触发级联中, Db2 则回滚步骤5及所有先前步骤中作出的所有更改。

例如,表 DEPT 是 EMP 的父表,条件如下:
  • DEPT的DEPTNO列是主键。
  • EMP的WORKDEPT列是外键。
  • 约束条件为“删除时置空”。
假设在EMP上定义了以下触发器:
CREATE TRIGGER EMPRAISE
  AFTER UPDATE ON EMP
  REFERENCING NEW TABLE AS NEWEMPS
  FOR EACH STATEMENT MODE DB2SQL
  BEGIN ATOMIC
    VALUES(CHECKEMP(TABLE NEWEMPS));
  END
假设一条SQL语句从DEPT表中删除了部门编号为 E21 的行。 由于存在限制, Db2 在EMP中找到WORKDEPT值为 E21 的行,并将这些行中的WORKDEPT设置为空。 这相当于对EMP的更新操作,EMP具有更新触发器EMPRAISE。 因此,由于EMPRAISE是后触发器,EMPRAISE在约束操作将WORKDEPT值设置为空后激活。