2012-08-28 6 views
0

DB2 V9 Z/OsDB2 procédure stockée à l'aide d'un curseur

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 

La procédure ci-dessus stockée construit avec un code de cond 0, mais ne parvient pas à exécuter même lorsqu'une consumer_id spécifique. Est-ce que quelqu'un voit quelque chose de mal?

Les instructions SQL individuelles s'exécutent exactement comme elles le devraient.

J'ai suivi les exemples de curseurs dans les procédures SQL d'IBM.

Merci

+1

Vous savez que cela pourrait (probablement) être mieux fait sans le curseur, n'est-ce pas? A savoir, cela peut être fait dans une seule instruction UPDATE, en supposant que la taille des lignes mises à jour n'est pas trop grande (pour la transaction). Préférer les instructions 'normales' sur les curseurs la plupart du temps, sauf si le jeu de résultats est soit paginé (comme lors de l'affichage à un utilisateur), soit mis à jour/supprimer/tout ce qui doit être 'batché' (si le nombre de lignes verrouillées trop grande). –

Répondre

1

Je suis d'accord à 100% avec @ X-Zero, cela semble être une énorme quantité de travail définissant les curseurs et ce-pas, quand vous pourriez faire une opération en fonction de configuration simple (probablement avec de meilleures performances). Voici deux exemples de la façon dont vous pouvez le faire avec une seule opération:

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 
) 

Nouvelle 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 

Ils ont été testés sur DB2 pour Linux/Unix/Windows v9.7, mais devrait fonctionner sur n'importe quelle version de DB2 plus récente que 9.1 (DB2 pour iSeries est un joker, je ne me souviens jamais de ce que cette plate-forme supporte ou non :))

+0

Mon iSeries ne supporte pas 'MERGE', mais le premier devrait fonctionner correctement (ce qui était exactement ce à quoi je pensais). –

-1

La commande FETCH doit être dans le WHILE, de sorte que chaque fois qu'elle est invoquée, elle récupère une ligne.

Questions connexes