Chinaunix

标题: 关于游标cursor的BUG??? [打印本页]

作者: leojing    时间: 2005-01-10 15:16
标题: 关于游标cursor的BUG???
存储过程中的游标!!!

--申明游标
DECLARE CURVSLLAND CURSOR FOR
___SELECT MAINKEY FROM VSAGENTLIB.VSLLAND WHERE ISVALID = '1' ;
DECLARE CONTINUE HANDLER FOR not found SET AT_END = 1 ;

fetch_loop:
LOOP
___FETCH CUR_VSLLAND INTO LL_MAINKEY ;
___IF at_end = 1 THEN
______LEAVE fetch_loop;
___END IF;
___select  BERTHCODE  INTO cCURRBERTHC from ..where...
___--①一个Select语句,这个语句有可能没有满足Where的结果
___if IFNULL( cCURRBERTHC , '' ) <>; '' THEN
______...
___else
______...
___end
end loop
当①处,没有满足Where的结果时,会影响游标的行,下次循环时,游标误认为已经结束,退出。
请问各位有没有见到过?有什么解决办法,谢谢
作者: xuguopeng    时间: 2005-01-10 16:01
标题: 关于游标cursor的BUG???
找了点以前的关于游标的代码,你看看吧
  1. DB2下游标控制不是非常的轻松和方便的,同样也可以使用sqlcode,sqlstate,或者用户自己控制,DB2下SQLCODE,SQLSTATE不能直接使用,必须声明后使用,(也就是说将系统的SQLCODE,SQLSTATE本地实例化一分拷贝)。一般采用用户定义游标开关和sqlcode返回信息一起共同控制的方法.


  2. 举例1:(这里说明一个问题,游标开关是和SQLCODE捆绑的。‘02000’就是SQLCODE号)


  3. //-------


  4. 标准使用游标的例子


  5. 标准WHILE DO 控制游标


  6. //-------





  7. CREATE PROCEDURE CREDITP              


  8. (IN i_perinc DECIMAL(3,2),


  9. INOUT o_numrec DECIMAL(5,0))


  10. LANGUAGE SQL


  11. BEGIN                                      -- 这里是用户管理事务


  12. DECLARE proc_cusnbr CHAR(5);


  13. DECLARE proc_cuscrd DECIMAL(11,2);


  14. DECLARE numrec DECIMAL(5,0);


  15. DECLARE at_end INT DEFAULT 0;              -- 开关定义                     


  16. DECLARE not_found  CONDITION FOR '02000';  -- 没有数据,游标结尾定义                              


  17. DECLARE c1 CURSOR FOR SELECT cusnbr, cuscrd  FROM ordapplib.customer;





  18. DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;        --定义CONTINUE 条件





  19. DECLARE EXIT HANDLER FOR SQLEXCEPTION     ROLLBACK ;          --sqlcode 非'01''00''02'则退出并回滚事务


  20. SET numrec = 0;





  21. OPEN c1;


  22.     FETCH c1 INTO proc_cusnbr, proc_cuscrd;


  23. WHILE at_end = 0 DO


  24.     SET proc_cuscrd = proc_cuscrd +(proc_cuscrd * i_perinc);


  25.     SET numrec = numrec + 1;


  26.     FETCH c1 INTO proc_cusnbr, proc_cuscrd;


  27. END WHILE;


  28. SET o_numrec = numrec;


  29. CLOSE c1;


  30. COMMIT;           --提交事务                 


  31. END





  32. 举例2:


  33. --声明游标C1


  34. DECLARE c1 CURSOR FOR


  35. SELECT cusnbr, cuscrd


  36. FROM ordapplib.customer;





  37. OPEN c1; --打开游标


  38. FETCH c1 INTO proc_cusnbr, proc_cuscrd; --从游标获取数据


  39. IF SQLSTATE = '02000' THEN  --判断游标是否有数据(无)


  40. CALL DATA_NOT_FOUND;    --返回调用


  41. ELSE


  42. DO WHILE (SUBSTR(SQLSTATE,1,2) = '00' | SUBSTR(SQLSTATE,1,2) = '01');


  43. FETCH c1 INTO proc_cusnbr, proc_cuscrd;


  44. ......





  45. END IF ;


  46. CLOSE c1;  --关闭游标
复制代码

作者: leojing    时间: 2005-01-10 16:16
标题: 关于游标cursor的BUG???
谢谢先。上面的例子,在DB2的PDF中已经有。
IBM的示例的游标中,仅是一些简单的运算,而没有复杂的SQL
继续等待....
作者: xuguopeng    时间: 2005-01-10 16:30
标题: 关于游标cursor的BUG???
你问的不就是游标的用法么??

SQL的用法你可以去查SQL REFERENCE
作者: qingzhou    时间: 2005-01-10 22:52
标题: 关于游标cursor的BUG???
在“select BERTHCODE INTO cCURRBERTHC from ..where...
___--①一个Select语句,这个语句有可能没有满足Where的结果
” 语句后最好加上错误处理:

SELECT
WHEN  SQLCOD <0
EXSR    SQLERROR
WHEN  SQLCOD =100
EXSR    SQLNOROW
WHEN  SQLCOD >;0 OR SQLWN0<>;*BLANKS
EXSR    SQLWARNING
ENDSL
作者: leojing    时间: 2005-01-11 11:53
标题: 关于游标cursor的BUG???
从IBM服务人员得到的答案

在DB2种任何SELECT语句如果出现NOT_FOOD事件,都会进入HANDLER for NOT_FOUND中。
这样当你的SELECT语句找不到时,就进入了HANDLER。而HANDLER并不清楚该NOT_FOUND
是由SELECT因其的还是CURSOR引起的。

建议在CURSOR之间设立标志位,供HANDLER判断CURSOR的位置。

int mark1;

DECLARE HANDLER
BEGIN

IF mark1 == 0 THEN ;

IF mark1 == 1 THEN ;

END

LOOP:

set mark1 = 0

Fetch XXXXXXXX

Set mark1 = 1

SELECT XXXXXX
作者: wildfish    时间: 2005-01-11 18:37
标题: 关于游标cursor的BUG???
原帖由 "qingzhou" 发表:
在“select BERTHCODE INTO cCURRBERTHC from ..where...
___--①一个Select语句,这个语句有可能没有满足Where的结果
” 语句后最好加上错误处理:

SELECT
WHEN  SQLCOD <0
EXSR    SQLERROR
WHEN..........

这个用于sqlrpg,呵呵,帮助我奠定了sqlrpgle的标准化写法,
接下去想尝试一下free格式
但是发现函数的写法变化很大:(




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2