如何在IBM iSeries DB2 SQL触发器中获取触发的文件成员与库
在IBM i SQL触发器中获取触发文件的成员名与库名
可以实现,但SQL触发器无法直接访问RPGLE触发器专属的Parm1缓冲区,需通过以下两种方式获取所需信息:
方法1:使用SQL内置函数直接获取
IBM i的SQL提供了专门函数来获取对象和行的成员信息,无需依赖RPGLE触发器缓冲区:
- 获取成员名:使用
MEMBER_NAME()函数,传入触发器定义中的行变量(如N或O),即可返回该行所属的文件成员名称。 - 获取库名:使用
LIBRARY_NAME()函数结合触发对象ID,或直接使用触发器关联的库名(如需动态获取,可查询系统表实现)。
修改你的SQL触发器代码示例:
CREATE OR REPLACE TRIGGER TRGTESTFILE AFTER INSERT OR DELETE OR UPDATE ON MYLIB.TESTFILE1 REFERENCING NEW ROW AS N OLD ROW AS O FOR EACH ROW MODE DB2ROW BEGIN DECLARE TSTAMP TIMESTAMP; DECLARE TRIGGER_LIB CHAR(10); DECLARE TRIGGER_MBR CHAR(10); -- 获取触发的库名和成员名 SET TRIGGER_LIB = LIBRARY_NAME(OBJECT_ID('MYLIB.TESTFILE1')); SET TRIGGER_MBR = CASE WHEN INSERTING THEN MEMBER_NAME(N) WHEN UPDATING THEN MEMBER_NAME(N) WHEN DELETING THEN MEMBER_NAME(O) END; IF INSERTING THEN INSERT INTO MYLIB.OUTFILE VALUES(TRIGGER_LIB, TRIGGER_MBR, 'I', N.ID, N.NAME); END IF; -- 可继续添加UPDATE/DELETE的处理逻辑 END;
方法2:调用RPGLE程序获取完整触发器缓冲区信息
如果需要获取Parm1中的所有字段(如触发事件、时间等),可以在SQL触发器中调用自定义RPGLE程序,由该程序读取触发器缓冲区并返回所需信息:
- 编写RPGLE程序(需启用触发器缓冲区支持):
dcl-ds Parm1 qualified; File char(10); // File name Library char(10); // Library file is in Member char(10); // Member name TriggerEvent char(1); // Trg event 1=Add 2=Delete 3=Change TriggerTime char(1); // Trigger time CommitLock char(1); // Commit lock level *n char(3); // Reserved CCSID int(10); // CCSID *n char(8); // Reserved end-ds; dcl-pi *n; outLib char(10) options(*omit); outMbr char(10) options(*omit); end-pi; // 读取触发器缓冲区 parm1 = %trigger(); // 返回库名和成员名 if %addr(outLib) <> *null; outLib = parm1.Library; endif; if %addr(outMbr) <> *null; outMbr = parm1.Member; endif;
- 在SQL触发器中调用该程序:
CREATE OR REPLACE TRIGGER TRGTESTFILE AFTER INSERT OR DELETE OR UPDATE ON MYLIB.TESTFILE1 REFERENCING NEW ROW AS N OLD ROW AS O FOR EACH ROW MODE DB2ROW BEGIN DECLARE TSTAMP TIMESTAMP; DECLARE TRIGGER_LIB CHAR(10); DECLARE TRIGGER_MBR CHAR(10); -- 调用RPGLE程序获取库名和成员名 CALL MYLIB.GET_TRIGGER_INFO(TRIGGER_LIB, TRIGGER_MBR); IF INSERTING THEN INSERT INTO MYLIB.OUTFILE VALUES(TRIGGER_LIB, TRIGGER_MBR, 'I', N.ID, N.NAME); END IF; END;
注意事项
MEMBER_NAME()函数仅对多成员文件有效,单成员文件会返回默认成员名。- 调用RPGLE程序时,需确保程序已正确编译并授予触发器足够的执行权限。
内容的提问来源于stack exchange,提问作者OutLander
相关产品推荐
相关产品推荐

