DB2使用光标

DB2使用光标

问题描述:

DB2 V9的z/OSDB2使用光标

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过程中游标的示例。

谢谢

+1

你知道这可能(可能)做得更好_overout光标,对不对?也就是说,假设更新行的大小不是太大(对于事务),这可以在单个“UPDATE”语句中完成。除非结果集是分页的(比如向用户显示时),或者更新/删除/需要“分批”(如果锁定的行数是太大了)。 –

我同意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测试的Linux/Unix/Windows v9.7,但应该在任何版本的DB2比9.1更新的版本上工作(DB2 for iSeries是通配符,我从来不记得那个平台做什么或不支持:)

+0

我的iSeries不支持'MERGE',但第一个应该可以正常工作(这正是我所想的)。 –

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