Stored procedures DB2fori存储过程中的多个Continue处理程序

Stored procedures DB2fori存储过程中的多个Continue处理程序,stored-procedures,db2,ibm-midrange,db2-400,Stored Procedures,Db2,Ibm Midrange,Db2 400,我正在IBM I V7R2 TR3上使用DB2 for I 我试图编写一个包含两个SELECT语句的存储过程。第一个我用光标循环通过,第二个在循环内。如果从第二个(内部)选择返回记录,则我需要中断循环,否则继续。我已经看到了异常处理程序的例子,但是当我试图实现它们时,我会在第一次迭代时被抛出循环。关于异常处理程序为什么对我不起作用,我的假设是因为我正在全局级别设置异常处理程序,并且当第二个(内部)选择在第一次迭代中返回零结果时(它将大部分返回零行),异常处理程序是触发器,我中断了存储过程,而不仅

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

我试图编写一个包含两个
SELECT
语句的存储过程。第一个我用光标循环通过,第二个在循环内。如果从第二个(内部)
选择
返回记录,则我需要中断循环,否则继续。我已经看到了
异常处理程序的例子,但是当我试图实现它们时,我会在第一次迭代时被抛出循环。关于
异常处理程序
为什么对我不起作用,我的假设是因为我正在全局级别设置
异常处理程序
,并且当第二个(内部)
选择
在第一次迭代中返回零结果时(它将大部分返回零行),异常处理程序是触发器,我中断了存储过程,而不仅仅是循环

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

我已经尝试了一些替代方法来
异常处理程序
,这就是我目前拥有的。我对异常处理程序不是一成不变的,但如果知道如何使用多个异常处理程序,那就太好了

以下是我的存储过程(带有已更改的库/表),如果有帮助,可供参考:

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

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

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。。。结束
块并在该块内声明处理程序。

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

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。。。结束
block并在该块中声明处理程序。

谢谢你的回答,我必须切换一些其他(大部分不相关)的东西才能在我的特定用例中工作,但这正是需要的。谢谢你的回答,我必须切换一些其他(大部分不相关)的东西让它在我的特定用例中工作,但这正是需要的。我知道你有你的答案……但我只是想说SQL不是RPG。您应该考虑集合操作,而不是使用光标逐行进行。我的座右铭(对SQL新手来说)如果你使用游标,你就做错了。是的,有时您必须使用游标,但对于RPG(或其他程序)程序员来说,在不需要游标时使用游标太容易了。我建议在你的代码、输入和预期输出以及表格样本中发布一个新问题,看看是否有人能向你展示基于集合的解决方案。我和Charles在一起——你可以在一句话中完成这一点(而且更快)。哦,您有一个较小的SQL注入漏洞,因为您正在连接字符串进行搜索。由于它们只有20个字符,所以不太容易被利用,但您仍然应该使用参数标记。在考虑您的建议时,我对存储过程做了很多修改。不管是哪种方式,我已经发布了一个关于消除游标使用的新问题,正如您在这里建议的那样,从itemtable中选择*,其中baseitem=initem连接子字符串前缀(某物或其他)前缀Good LuckI看到你有你的答案了…但我只是想说SQL不是RPG。您应该考虑集合操作,而不是使用光标逐行进行。我的座右铭(对SQL新手来说)如果你使用游标,你就做错了。是的,有时您必须使用游标,但对于RPG(或其他程序)程序员来说,在不需要游标时使用游标太容易了。我建议在你的代码、输入和预期输出以及表格样本中发布一个新问题,看看是否有人能向你展示基于集合的解决方案。我和Charles在一起——你可以在一句话中完成这一点(而且更快)。哦,您有一个较小的SQL注入漏洞,因为您正在连接字符串进行搜索。由于它们只有20个字符,所以不太容易被利用,但您仍然应该使用参数标记。在考虑您的建议时,我对存储过程做了很多修改。不管是哪种方式,我已经发布了一个关于消除游标使用的新问题,正如您在这里建议的那样,从itemtable中选择*,其中baseitem=initem连接子字符串前缀(某物或其他)前缀好运