在触发器主体中指定触发器的父架构

时间:2011-12-07 08:20:01

标签: database triggers database-schema ibm-midrange db2-400

DB2 for IBM System i 中,我创建了此触发器,用于在MYLOGTABLE上对每个插入操作MYCHECKEDTABLE进行记录:

SET SCHEMA MYSCHEMA;

CREATE TRIGGER MYTRIGGER AFTER INSERT ON MYCHECKEDTABLE
REFERENCING NEW AS ROWREF
FOR EACH ROW BEGIN ATOMIC
     INSERT INTO MYLOGTABLE -- after creation becomes MYSCHEMA.MYLOGTABLE
         (MMACOD, OPTYPE, OPDATE)
     VALUES (ROWREF.ID, 'I', CURRENT TIMESTAMP);
END;

DBMS使用MYSCHEMA.MYLOGTABLE硬编码存储触发器主体。

现在假设我们将整个架构复制为新架构NEWSCHEMA。当我在NEWSCHEMA.MYCHECKEDTABLE中插入记录时,日志记录将添加到MYSCHEMA.MYLOGTABLE而不是NEWSCHEMA.MYLOGTABLE,即在触发器及其表所在的架构中。这是大问题的原因!!此外,因为许多用户可以在没有我控制的情况下复制架构...

那么,有没有办法在触发器体中指定触发器所在的模式?这样我们就会用正确的MYLOGTABLE编写日志记录。类似于PARENT SCHEMA ......还是有解决方法? 非常感谢!

2 个答案:

答案 0 :(得分:1)

HLL中定义的外部触发器可以访问触发器缓冲区,该缓冲区包含触发触发器的表的库名。这可用于限定对MYLOGTABLE的引用。

有关详细信息,请参阅IBM红皮书Stored Procedures, Triggers, and User-Defined Functions on DB2 Universal Database for iSeries的第11.2章“触发器程序结构”。

或者,您可以使用CURRENT SCHEMA特殊注册表或GET DESCRIPTOR语句来查找触发器和/或表当前所在的位置。

答案 1 :(得分:0)

不幸的是,我意识到触发器内部的模式无法从触发器内部检测到

但有一些解决方法(感谢@krmilligan):

  • 取消用户执行CPYLIB的权限,并让他们使用实用程序。
  • 在peridiocally运行的系统上创建一个后台代理,查找不同步的触发器。
  • 对于命令CPYLIB,将TRG选项的默认设置设为*NO 。这样,除非用户明确指定,否则永远不会复制触发器。

我选择最后一个,因为它是最简单的一个,即使可能存在需要触发器复制的上下文。在这种情况下,我会采取第一种解决方法。