代码之家  ›  专栏  ›  技术社区  ›  d.lanza38

DB2 for i存储过程中的多个Continue句柄

  •  1
  • d.lanza38  · 技术社区  · 9 年前

    我正在IBM I V7R2 TR3上使用DB2 for I

    我正在尝试编写一个包含两个 SELECT 声明。我用光标循环其中的第一个,第二个在循环的内部。如果从第二个(内部)返回记录 选择 那么我需要跳出循环,否则继续。我看过一些例子 Exception Handlers ,但当我试图实现它们时,我会在第一次迭代时被排除在循环之外。我对原因的假设 异常处理程序 不要为我工作,因为我正在设置 Exception Handler 在全局级别,当第二个(内部) 选择 在第一次迭代期间返回零个结果(它将主要返回零行),异常处理程序是触发器,我中断了存储过程而不仅仅是循环。

    如何设置多个 异常处理程序 在特定SQL语句的单个存储过程中?我读过DB2中的复合语句,但不知道如何指定 异常处理程序 是的。

    https://www-01.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/com.ibm.db2z11.doc.sqlref/src/tpc/db2z_compoundstatement4nativesqlpl.html

    我尝试了一些替代方法 异常处理程序 这就是我目前拥有的。我还没准备好 异常处理程序 ,但如果知道如何使用多个 异常处理程序 .

    以下是我的存储过程(带有更改的lib/tables),如果有帮助,请参考:

    DECLARE EOF1 INT DEFAULT 0 ; 
    DECLARE EOF2 INT DEFAULT 0 ; 
    DECLARE CURMATCH CHAR ( 20 ) DEFAULT '' ; 
    DECLARE CURPREFIX CHAR ( 20 ) DEFAULT '' ; 
    DECLARE PREFIXES CURSOR FOR 
        SELECT  TRIM ( PREFIX ) || '%' 
        FROM    MYLIB / PREFIXTABLE 
        ORDER BY    LENGTH ( TRIM ( PREFIXCOL ) ) DESC , TRIM ( PREFIXCOL ) DESC ; 
    
    
    
    OPEN PREFIXES ; 
    WHILE EOF1 = 0 DO 
    
        FETCH FROM PREFIXES INTO CURPREFIX ; 
    
        IF TRIM ( CURPREFIX ) = '' THEN 
            SET EOF1 = 1 ; 
        END IF ; 
    
        SELECT  DISTINCT BASEITEM , 
            SUBSTR ( BASEITEM , 
            ( LENGTH ( TRIM ( CURPREFIX ) ) + 1 ) , ( 20 - LENGTH ( TRIM ( CURPREFIX ) ) ) 
        ) INTO CURMATCH 
        FROM    MYLIB / ITEMTABLE 
        WHERE   BASEITEM = ITEM 
        AND CASE 
                WHEN BASEITEM LIKE '' || CURPREFIX || '' THEN 1 
                ELSE 0 
            END = 1 ;        
    
        IF ( TRIM ( CURMATCH ) <> '' ) THEN 
            SET BASEITEM = TRIM ( CURMATCH ) ; 
            SET EOF2 = 1 ; 
        END IF ; 
        IF EOF2 <> 0 THEN 
            SET EOF1 = 1 ; 
        END IF ; 
    
    END WHILE ; 
    CLOSE PREFIXES ; 
    
    IF(EOF2 = 0) THEN 
        SET BASEITEM = 'NOT FOUND'; 
    END IF; 
    

    存储过程设置为接受定义的2个参数:

    IN ITEM CHAR(20) CCSID 37 DEFAULT  ''  , 
    INOUT BASEITEM CHAR(20) DEFAULT  '' 
    

    我忘了提到上面的代码似乎创建了一个无限循环。当我调用这个程序时,它一直在运行,不会停止。在杀死它之前,我让它运行了10分钟,考虑到这些表中的记录数量,我认为不会花那么长时间。

    1 回复  |  直到 8 年前
        1
  •  4
  •   mustaccio Gandalf    9 年前

    信号(异常)处理程序位于声明它们的块的本地。过程主体是最外部的块,但可以定义嵌套块。由于您没有发布代码(带有信号处理程序的代码),我无法确切地告诉您如何修改它,但一般来说,它看起来像这样:

    CREATE PROCEDURE yourproc
    ...
    BEGIN
      DECLARE prefixes CURSOR FOR ...
      OPEN PREFIXES ; 
      WHILE EOF1 = 0 DO 
        FETCH FROM PREFIXES INTO CURPREFIX ; 
        BEGIN -- inner block
          DECLARE CONTINUE HANDLER FOR ...
          ... -- do whatever
        END; -- inner block
      END WHILE ; 
      ...
    END -- procedure
    

    基本上,您将希望处理其信号的语句包装在 BEGIN ... END 块并在该块内声明处理程序。