Comment Updater lors du Fetch d'un Curseur SQL ?

RPG (3 et 4, free), CL, SQL, etc...
Répondre
germor
Messages : 75
Enregistré le : lun. 06 juin 2011, 08:01:43

Comment Updater lors du Fetch d'un Curseur SQL ?

Message par germor »

Bonjour,
En V7R1,

Le code suivant renvoie un status SQLSTT 42828 :

Code : Tout sélectionner

         EXEC SQL
          DECLARE CUR1 CURSOR FOR
            SELECT * FROM TABLE1 A
            LEFT JOIN TABLE2 B ON A.A6IDCPTIND = B.E8IDCPTIND
            LEFT JOIN TABLE3 C ON C.EBIDCOUPLE = B.E8IDCOUPLE
            LEFT JOIN TABLE4 D ON C.EBCOPRODUI = D.A1COPRODUI
            WHERE A.ZONE1 LIKE '123456%'
            AND A.ZONE2 = '9999-12-31'
            AND D.ZONE55 = 'champ1';

         EXEC SQL
         OPEN CUR1;

         EXEC SQL
          FETCH NEXT FROM CUR1;

         dow SqlCode >= 0 and SqlCode < 100;

         EXEC SQL
          UPDATE TABLE1 
          SET ZONE3 = 'AAA'
          WHERE CURRENT OF CUR1;

         EXEC SQL
          FETCH NEXT FROM CUR1;

         EndDo;

         EXEC SQL
          CLOSE CUR1;      
en rajoutant FOR UPDATE, la compil renvoie un code SQLCOD 0511 (La clause FOR UPDATE est incorrecte.) :

Code : Tout sélectionner

         EXEC SQL
          DECLARE CUR1 CURSOR FOR
            SELECT * FROM TABLE1 A
            LEFT JOIN TABLE2 B ON A.A6IDCPTIND = B.E8IDCPTIND
            LEFT JOIN TABLE3 C ON C.EBIDCOUPLE = B.E8IDCOUPLE
            LEFT JOIN TABLE4 D ON C.EBCOPRODUI = D.A1COPRODUI
            WHERE A.ZONE1 LIKE '123456%'
            AND A.ZONE2 = '9999-12-31'
            AND D.ZONE55 = 'champ1'
            &#91;b&#93;WITH NC
            FOR UPDATE OF ZONE3&#91;/b&#93;;  
Le fait qu'il y ait plusieurs tables dans le FROM génère apparemment ce code.
Auriez-vous un moyen pour permettre au programme de mettre à jour le poste de la table "principale" lu par le FETCH du Curseur ?
Merci de vos réponses.

Ca a l'air de fonctionner comme voulu en modifiant le curseur comme ci :

Code : Tout sélectionner

            
         EXEC SQL
          DECLARE CUR1 CURSOR FOR
            SELECT * FROM TABLE1 A
             WHERE A.ZONE1 LIKE '123456%'
            AND A.ZONE2 = '9999-12-31'
            AND A.CLE1 IN
                &#40;SELECT AA.CLE1 FROM TABLE1 AA
                 LEFT JOIN TABLE2 B ON AA.A6IDCPTIND = B.E8IDCPTIND
                 LEFT JOIN TABLE3 C ON C.EBIDCOUPLE = B.E8IDCOUPLE
                 LEFT JOIN TABLE4 D ON C.EBCOPRODUI = D.A1COPRODUI
                 WHERE D.ZONE55 = 'champ1'&#41;
            WITH NC
            FOR UPDATE OF ZONE3 
Maintenant, il faut voir si ce n'est pas optimisable.

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

FOR UPDATE

Message par cmasse »

Bon, en fait vous avez déjà tout compris.

ON ne peut mettre à jour avec WHERE CURRENT OF ... que si on a indiqué FOR UPDATE dans le DECLARE CURSOR.


MAIS

certaines requêtes ne sont pas "updatables" (désolé pour cet anglicisme) comme l'indique SQL0511. Dès qu'il y a JOIN ou GROUP BY.


Donc, il vous reste

a/ à placer une requête modifiable, votre dernier exemple le prouve.

b/ ou à faire un UPDATE sur la clé


-> WHERE CLE = xxx plutôt que WHERE CURRENT OF


Dernier point , analyser votre requête avec Visual Explain, vous verrez que les clauses IN ou EXISTS utilisent les mêmes méthodes qu'une jointure , NOT IN ou NOT EXISTS, les mêmes que EXCEPTION JOIN
Christian Massé (Volubis.fr)

Répondre