使用存储过程调用的BEFORE INSERT触发器(DB2LUW 9.5) [英] BEFORE INSERT trigger with stored procedure call (DB2 LUW 9.5)

查看:22
本文介绍了使用存储过程调用的BEFORE INSERT触发器(DB2LUW 9.5)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个BEFORE INSERT触发器,该触发器将检查一个字段的传入值,如果该字段为空,则将其替换为另一行中的相同字段。但是,当我将CALL语句添加到我的触发器时,返回错误"The trigger "ORGSTRUCT.CSTCNTR_IN" is defined with an unsupported triggered SQL statement"。我查看了文档,发现之前的版本不支持游标(这是创建存储过程的部分原因),但即使我从存储过程中删除了游标声明,调用仍会生成相同的错误。

触发器:

CREATE TRIGGER orgstruct.cstcntr_IN
        NO CASCADE
        BEFORE INSERT ON orgstruct.tOrgs
        REFERENCING NEW AS r
        FOR EACH ROW MODE DB2SQL
BEGIN ATOMIC
    DECLARE prnt_temp BIGINT;
    DECLARE cstcntr_temp CHAR(11);

    SET prnt_temp = r.prnt;
    SET cstcntr_temp = r.cstcntr;

    CALL orgstruct.trspGetPrntCstCntr(prnt_temp,cstcntr_temp);
    SET r.cstcntr = cstcntr_temp;
END

存储过程:

CREATE PROCEDURE orgstruct.trspGetPrntCstCntr (
    IN  p_prnt              BIGINT,
    OUT p_cstcntr       CHAR(11)
)
SPECIFIC trGetPrntCstCntr
BEGIN
    IF p_prnt IS NULL THEN
        RETURN;
    END IF;

    BEGIN
        DECLARE c1 CURSOR
            FOR
                SELECT cstcntr
                FROM orgstruct.tOrgs
                WHERE id = p_prnt
            FOR READ ONLY;
        OPEN c1;
        FETCH FROM c1 INTO p_cstcntr;
        CLOSE c1;
    END;
END

根据文档,CALLBEFORE触发器中是允许的,所以我不明白问题出在哪里。

推荐答案

BEFORE触发器可以调用存储过程,但存储过程不能执行触发器中不允许的任何操作。

在您的例子中,SQL存储过程的默认数据访问级别是MODIFIES SQL DATA,这在触发器中是不允许的。您可以重新创建存储过程,将数据访问级别更改为READS SQL DATA;这将允许您创建触发器。

然而:没有理由为这么简单的事情调用存储过程;您可以使用简单的内联触发器来实现:

create trigger orgstruct.cstcntr_IN
   no cascade
   before insert on orgstruct.tOrgs
   referencing new as r
   for each row
   mode db2sql
   set r.cstcntr = case 
                     when r.p_prnt is not null 
                       then (select cstcntr from tOrgs where id = r.p_prnt fetch first 1 row only) 
                     else r.cstcntr 
                   end;
这将大大提高效率,因为它消除了存储过程调用和存储过程中的游标处理。即使您希望使用存储过程,也可以消除存储过程中的游标并提高性能。

仅供参考:您发布的逻辑包含错误,并且将始终将CSTCNTR设置为空。此答案中发布的触发器不能做到这一点。:-)

这篇关于使用存储过程调用的BEFORE INSERT触发器(DB2LUW 9.5)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆