0

DB2 V9 Z/O

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 の Cursors in SQL Procedures の例に従いました。

ありがとうございました

4

2 に答える 2

1

I agree 100% with @X-Zero, this seems like a huge amount of work defining cursors and what-not, when you could do a simple set-based operation (likely with better performance). Here are two examples of how you can do it with a single operation:

Normal 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
)

New MERGE hotness:

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

These were tested on DB2 for Linux/Unix/Windows v9.7, but should work on any version of DB2 newer than 9.1 (DB2 for iSeries is a wildcard, I never remember what that platform does or doesn't support :) )

于 2012-08-29T16:10:00.290 に答える
-1

FETCH コマンドは、呼び出されるたびに行をフェッチするように、WHILE 内にある必要があります。

于 2015-03-30T16:47:52.317 に答える