使用游标的DB2存储过程

时间:2012-08-28 19:17:19

标签: stored-procedures cursor db2 updating

DB2 V9 Z / Os

CREATE PROCEDURE SERDB.I21MMSNOUPD () 
RESULT SETS 1
LANGUAGE SQL
FENCED
COLLID SER
WLM ENVIRONMENT DDSNSPENV
RUN OPTIONS 'NOTEST(NONE,*,*,*)'

P1: BEGIN

--Declare variables
DECLARE CONSUMER        INTEGER;
DECLARE NEW_MMS_NO      INTEGER;
DECLARE END_TABLE       INT DEFAULT 0;


DECLARE C1 CURSOR FOR 
SELECT I20_CONSUMER_ID,
       NEW_MMS_NO
  FROM SERDB.I20_TEMP
-- WHERE I20_CONSUMER_ID = 164921;
ORDER BY I20_CONSUMER_ID;

DECLARE CONTINUE HANDLER FOR NOT FOUND
 SET END_TABLE = 1;  

OPEN C1;
FETCH C1 INTO CONSUMER,
          NEW_MMS_NO;

WHILE END_TABLE = 0 DO              

UPDATE SERDB.I20_CONSUMER_T
   SET I20_MMS_NO = NEW_MMS_NO
 WHERE I20_CONSUMER_ID = CONSUMER;

END WHILE;

CLOSE C1;              
END P1

上面的存储过程使用cond代码0构建,但即使在特定的consumer_id时也无法执行。有人看错了吗?

单个sql语句完全按照预期运行。

我已经按照IBM的SQL过程中的游标示例进行了操作。

谢谢

2 个答案:

答案 0 :(得分:1)

我同意100%使用@ X-Zero,当你可以做一个简单的基于集合的操作(可能具有更好的性能)时,这似乎是定义游标和什么不是很多的工作。以下是两个如何通过单个操作完成此操作的示例:

正常UPDATE

UPDATE SESSION.I20_CONSUMER_T A
SET I20_MMS_NO = (
    SELECT NEW_MMS_NO
    FROM SESSION.I20_TEMP B
    WHERE A.I20_CONSUMER_ID = B.CONSUMER
)
WHERE EXISTS (
    SELECT 1
    FROM SESSION.I20_TEMP C
    WHERE A.I20_CONSUMER_ID = C.CONSUMER
)

MERGE热度:

MERGE INTO SESSION.I20_CONSUMER_T AS T
USING SESSION.I20_TEMP AS M
   ON T.I20_CONSUMER_ID = M.CONSUMER
WHEN MATCHED THEN
    UPDATE SET T.I20_MMS_NO = M.NEW_MMS_NO
ELSE IGNORE

这些在DB2 for Linux / Unix / Windows v9.7上进行了测试,但是应该适用于比9.1更新的任何版本的DB2(DB2 for iSeries是一个通配符,我永远不会记得该平台支持或不支持的内容{ {1}})

答案 1 :(得分:-1)

FETCH命令必须位于WHILE内部,以便每次调用它时都会获取一行。