Create After Trigger 有效,但 Create Before 无效

Posted

技术标签:

【中文标题】Create After Trigger 有效,但 Create Before 无效【英文标题】:Create After Trigger works but Create Before doesn't 【发布时间】:2021-01-26 12:00:12 【问题描述】:

如果我尝试如下创建一个带有 After 的触发器,它工作正常。

CREATE TRIGGER UDO.TG_TEST AFTER UPDATE
    OF LAST_BACKUP ON
    UDO.BACKUP FOR EACH ROW
INSERT
    INTO
    UDO.BACKUP_HIST(BACKUP_ID,
    INST_NAME,
    INST_ID,
    DB_NAME,
    DB_ID,
    SERVER,
    RESTORE_TS,
    LAST_BACKUP,
    BACKUP_TYP,
    BACKUP_DAUER,
    BACKUP_ORT)
SELECT
    BACKUP_ID,
    INST_NAME,
    INST_ID,
    DB_NAME,
    DB_ID,
    SERVER,
    RESTORE_TS,
    LAST_BACKUP,
    BACKUP_TYP,
    BACKUP_DAUER,
    BACKUP_ORT
FROM UDO.BACKUP

但如果我执行完全相同的创建但使用 BEFORE 或 NO CASCADE BEFORE:

CREATE TRIGGER UDO.TG_TEST NO CASCADE BEFORE UPDATE
    OF LAST_BACKUP ON
    UDO.BACKUP FOR EACH ROW
INSERT
    INTO
    UDO.BACKUP_HIST(BACKUP_ID,
    INST_NAME,
    INST_ID,
    DB_NAME,
    DB_ID,
    SERVER,
    RESTORE_TS,
    LAST_BACKUP,
    BACKUP_TYP,
    BACKUP_DAUER,
    BACKUP_ORT)
SELECT
    BACKUP_ID,
    INST_NAME,
    INST_ID,
    DB_NAME,
    DB_ID,
    SERVER,
    RESTORE_TS,
    LAST_BACKUP,
    BACKUP_TYP,
    BACKUP_DAUER,
    BACKUP_ORT
FROM UDO.BACKUP

我收到以下错误:

SQL-Fehler [42987]:触发器“UDO.TG_TEST”是使用不受支持的触发 SQL 语句定义的。SQLCODE=-797, SQLSTATE=42987, DRIVER=3.72.44

我根据IBM DB2 documentation检查了语法,我认为是正确的。

我忽略了什么吗?

编辑:

平台:LUW, DB2 服务器版本:11.1.4.4

我的实际目标是在更新 UDO.BACKUP 之前将 UDO.BACKUP 中的数据存档到 UDO.BACKUP_HIST。

【问题讨论】:

编辑您的问题并显示失败的代码。 当您使用 Db2-for-LUW 时,您不应使用或参考 Db2 for Z/OS 文档(因为可以应用不同的语法规则)。始终仅使用与您的 Db2 平台和版本正确匹配的 Db2 知识中心。 【参考方案1】:

是的,您在提供的链接中忽略了以下内容:

之前没有级联 指定触发器是前触发器。 Db2 在应用由插入引起的任何更改之前执行触发的操作, 对主题表进行删除或更新操作。它还规定 触发的操作不会激活其他触发器,因为 前触发器的触发操作不能包含任何更新。 当还指定了 view-name 时,不得指定 NO CASCADE BEFORE。必须为 BEFORE 触发器指定 FOR EACH ROW。

“更新”是指 INSERT / UPDATE / DELETE / MERGE 语句。

【讨论】:

所以不可能通过触发器预先更新数据? 如果您确实有 DB2 for Z/OS,那么请改用 AFTER INSERT 触发器。如果您的数据库是 Db2 for LUW,则使用已编译的复合触发器 (BEGIN ... END),而不是内联复合触发器 (BEGIN ATOMIC ... END),如果您仅在 a 的主体内有一条语句,则隐式使用该复合触发器触发。 非常感谢您的帮助。它解决了我的问题:) 顺便说一句,以防万一:对于UDO.BACKUP 中的每个更新行,您都会在UDO.BACKUP_HIST 中获得UDO.BACKUP 表的完整副本。小心……

以上是关于Create After Trigger 有效,但 Create Before 无效的主要内容,如果未能解决你的问题,请参考以下文章

Trigger 触发器

MySQL触发器 trigger之after与before区分

PostgreSQL 9.4.2 中的“CREATE TRIGGER”使用啥锁(如果有)

MySQL Trigger AFTER INSERT ON 'table name' FOR EACH ROW WHEN (role_id = 3)

jQuery Mobile:更新导航栏时替代 .trigger('create') 或 .page()?

MySQL触发器trigger