2012-08-28 39 views
0

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」語句中完成。除非結果集是分頁的(比如向用戶顯示時),或者更新/刪除/需要「分批」(如果鎖定的行數是太大了)。 –

回答

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測試的Linux/Unix/Windows v9.7,但應該在任何版本的DB2比9.1更新的版本上工作(DB2 for iSeries是通配符,我從來不記得那個平臺做什麼或不支持:)

+0

我的iSeries不支持'MERGE',但第一個應該可以正常工作(這正是我所想的)。 –

-1

FETCH命令必須位於WHILE內部,以便每次調用時都會獲取一行。