在AS400中插入时更新触发器

时间:2016-10-13 07:13:45

标签: sql triggers db2 ibm-midrange

我正在尝试更新AS400中当前插入行的字段。我使用的是版本4.5,5.3和7.1。

对于我的测试,我创建了一个包含CRTDT字段的表WC(工作中心)(NUMERIC 7,0) 在此表中插入新记录时,我想检查此字段的值是否小于200,000,如果是,则添加1,000,000。

我的SQL是:

--  Generate SQL 
--  Version:                    V5R4M0 060210 
--  Generated on:               10/13/16 10:03:49 
--  Relational Database:        S65BEE7B 
--  Standards Option:           DB2 UDB iSeries 
CREATE TRIGGER RAVONLIB.WC_TRIGGER 
    AFTER INSERT ON RAVONLIB.WC 
    FOR EACH STATEMENT 
    MODE DB2SQL 
    SET OPTION  ALWBLK = *ALLREAD , 
    ALWCPYDTA = *OPTIMIZE , 
    COMMIT = *NONE , 
    DECRESULT = (31, 31, 00) , 
    DFTRDBCOL = *NONE , 
    DYNDFTCOL = *NO , 
    DYNUSRPRF = *USER , 
    SRTSEQ = *HEX   
    BEGIN ATOMIC 
IF WC.CRTDT<200000 THEN
    UPDATE RAVONLIB . WC SET CRTDT = 1000000 + CRTDT ; 
END IF;
END  ;

我收到一个错误,即变量CRTDT未定义或不可用。 在小于200000的情况下正确更新CRTDT的正确语法是什么?

2 个答案:

答案 0 :(得分:4)

您应该使用BEFORE INSERT触发器。

此外,您需要在插入时修改列值...您不能在刚刚插入的行的触发器中运行SQL UPDATE语句。

最后,您需要行触发器,而不是语句触发器。

CREATE TRIGGER RAVONLIB.WC_TRIGGER 
    BEFORE INSERT ON RAVONLIB.WC 
    REFERENCING NEW AS new_row
    FOR EACH ROW MODE DB2ROW
    SET OPTION  ALWBLK = *ALLREAD , 
    ALWCPYDTA = *OPTIMIZE , 
    COMMIT = *NONE , 
    DECRESULT = (31, 31, 00) , 
    DFTRDBCOL = *NONE , 
    DYNDFTCOL = *NO , 
    DYNUSRPRF = *USER , 
    SRTSEQ = *HEX   
    BEGIN ATOMIC 
IF new_row.CRTDT<200000 THEN
    SET new_row.CRTDT = 1000000 + new_row.CRTDT ; 
END IF;
END  ;

答案 1 :(得分:1)

FWiW,主要是教化,因为我对已经接受的答案的评论不是答案:如在v5r3上验证的那样,以下内容模仿语句从OP触发到逻辑结论;不知道谁会有一个v4r5系统可供测试 - ¡圣烟!

create table wc
( PKfld int not null
, CRTDT numeric(7)
, constraint WC_PK primary key (PKfld)
)             
;
CREATE TRIGGER wc_trg_ai                       
 After Insert on WC                            
REFERENCING NEW TABLE AS xt                    
FOR EACH STATEMENT  MODE DB2SQL                
SET OPTION COMMIT = *NONE                      
  BEGIN ATOMIC                                 
   update WC set WC.CRTDT = WC.CRTDT + 1000000 
   where WC.CRTDT<200000                       
     and exists ( select '1' from XT as xt     
                  where xt.PKfld = WC.PKfld ) ;
  END                                          
; -- semicolon as statement separator, not end of trigger-body
insert into wc values                                 
  (  1, '0000001'), (  2, '0200000'), (  3, '0000300')
, (  4, '0400000'), (  5, '0050000'), (  6, '0600000')
; -- per trigger dfn, the even-numbered key values will not see an UPDATE
select * from WC
; -- likeness of report from above query:
  PKFLD       CRTDT 
      1   1,000,001 
      2     200,000 
      3   1,000,300 
      4     400,000 
      5   1,050,000 
      6     600,000 
***  End of data  ***