PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 20/09/2022 14:13:22

Catherine
Membre

Incrémentation d'une colonne via un curseur

Bonjour,

Je vous remercie de m'indiquer quelle est mon erreur, je souhaite mettre à jour une colonne de table via un curseur qui la parcourt intégralement... Merci encore, Catherine.


DO $$

DECLARE
  cLecture CURSOR FOR SELECT * FROM EMA.TEST;
  rt EMA.TEST%ROWTYPE;
  NB Integer := 1;
   
BEGIN MAJ
OPEN cLecture;
LOOP
    FETCH ALL FROM cLecture;
    EXIT WHEN NOT FOUND; 
   
        UPDATE EMA.TEST SET NumLigne = NB WHERE CURRENT OF cLecture;
    COMMIT; 
    NB := NB + 1 ;

END LOOP ;

CLOSE cLecture;

END MAJ;
$$ LANGUAGE plpgsql;

Hors ligne

#2 20/09/2022 20:43:54

dverite
Membre

Re : Incrémentation d'une colonne via un curseur

Est-ce un exercice? Parce qu'en dehors d'un exercice, ça n'a aucun intérêt de faire une boucle au lieu d'un seul UPDATE qui met à jour toutes les lignes.


A part ça, il faut regarder la doc des curseurs en plpgsql pour les questions de syntaxe et d'usage: https://docs.postgresql.fr/14/plpgsql-cursors.html


Sinon le COMMIT en milieu de boucle pose problème: un COMMIT ferme la transaction en cours et par extension les curseurs qui sont ouverts dedans, sauf s'il sont marqués WITH HOLD. Mais pourquoi faire un COMMIT ici? Quel intérêt?

Hors ligne

#3 21/09/2022 05:14:55

Catherine
Membre

Re : Incrémentation d'une colonne via un curseur

Bonjour Daniel,

Merci pour votre réponse, mais je ne comprends pas comment faire un update incrémental d'une colonne sans boucle, avec Oracle, c'est possible via le rownum, mais pas avec PostGreSQL, si?

Le commit ferme la transaction, vraiment ?

Merci pour votre retour, Catherine.

Hors ligne

#4 21/09/2022 08:18:20

rjuju
Administrateur

Re : Incrémentation d'une colonne via un curseur

Merci pour votre réponse, mais je ne comprends pas comment faire un update incrémental d'une colonne sans boucle, avec Oracle, c'est possible via le rownum, mais pas avec PostGreSQL, si?

Vous pouvez utiliser row_number() over () pour obtenir la même chose.

Hors ligne

#5 21/09/2022 09:42:02

Catherine
Membre

Re : Incrémentation d'une colonne via un curseur

Merci Julien,

Mais cette fonction convient pour les select, pas pour les update, elle génère l'erreur : "ERREUR:  les fonctions de fenêtrage ne sont pas autorisés dans UPDATE."

Pour ma connaissance personnelle, j'aurais besoin de comprendre ce qui bloque dans ma boucle de lecture / mise à jour via curseur et fetch, s'il vous plait ...

Bonne journée, Catherine.

Hors ligne

#6 21/09/2022 09:52:04

rjuju
Administrateur

Re : Incrémentation d'une colonne via un curseur

Vous devez utiliser la syntaxe UPDATE ... FROM.  Par exemple:

UPDATE ema.test
SET numligne = rownum
FROM (SELECT pkcol, row_number() OVER () AS rownum) sub
WHERE sub.pkcol = ema.test.pkcol

Pour ma connaissance personnelle, j'aurais besoin de comprendre ce qui bloque dans ma boucle de lecture / mise à jour via curseur et fetch, s'il vous plait ...


Comme l'a indiqué Daniel, au moins le commit est problématique.  Si vous avez corrigé ce point, quelles erreurs avez-vous pour lesquelles la documentation pointée n'apporte pas de réponse ?

Hors ligne

#7 21/09/2022 11:34:29

Catherine
Membre

Re : Incrémentation d'une colonne via un curseur

Cette syntaxe retourne le message d'erreur suivant, même avec la création d'une PK sur la colonne id_vaccin ? "HINT:  Il existe une colonne nommée « id_vaccin » pour la table « test » mais elle ne peut pas être référencée dans cette partie de la requête."

Merci pour votre aide, savez-vous ce qui est faux dans la boucle du traitement initial, SVP?

Hors ligne

#8 21/09/2022 11:49:21

Catherine
Membre

Re : Incrémentation d'une colonne via un curseur

Avec toutes mes excuses, Julien, votre solution fonctionne très bien, c'est moi qui ai commis une erreur !
Si vous pouviez déboguer ma boucle, ce serait parfait !!!
Merci beaucoup, Catherine.

Hors ligne

#9 22/09/2022 19:45:29

dverite
Membre

Re : Incrémentation d'une colonne via un curseur

En vrac, il y a plusieurs soucis visibles dans le code montré


- BEGIN MAJ

Pourquoi MAJ? La syntaxe valide c'est BEGIN tout seul.


- FETCH ALL FROM cLecture;

La syntaxe est FETCH [ direction { FROM | IN } ] curseur INTO cible;

ALL n'est pas possible. La cible devrait probablement être rt la variable déclarée mais pas utilisée. S'il n'y a aucune cible à avoir, un MOVE cLecture ferait mieux l'affaire.

Attention au fait que la syntaxe du FETCH en plpgsql diffère du FETCH du SQL. C'est piégeux mais c'est une règle générale. Le plpgsql a sa propre syntaxe qui ressemble superficiellement au SQL mais qui diffère à cause des variables et du côté procédural.



- COMMIT à supprimer


- la requête du curseur n'a pas d'ORDER BY donc il faut voir que les valeurs successives de NB vont arriver dans les lignes dans un ordre indéterminé.

Hors ligne

#10 23/09/2022 15:19:44

Catherine
Membre

Re : Incrémentation d'une colonne via un curseur

Bonjour Daniel,

Merci, j'ai corrigé, ça tourne !
Bonne journée, Catherine.

Hors ligne

Pied de page des forums