Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Fonction return setof records avec plusieur OUT paramètres


Sujet :

Requêtes PostgreSQL

  1. #1
    Nouveau membre du Club
    Fonction return setof records avec plusieur OUT paramètres
    Bonjour,

    Je cherche à afficher un classement a partir d'une requete et d'afficher/renvoyer tous ca avecun SETOF RECORDS.
    J'ai cherché pendant un moment sur internet pour trouver une méthode utilisant des paramètres OUT.

    Je donc ébauché cela:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    CREATE OR REPLACE FUNCTION
    get_rewards_table(OUT nomSkieur VARCHAR, OUT nVictoire integer, OUT prime integer)
    RETURNS SETOF RECORD AS $$
    DECLARE
       cursor CURSOR FOR
        SELECT s.noSkieur, s.nomSkieur, COUNT(*) as nbVictoire
        FROM skieur AS s
        INNER JOIN classement as c on c.noSkieur = s.noSkieur
        WHERE c.classement = 1
        GROUP BY s.noSkieur, s.nomSkieur;
      r integer;
    BEGIN
      FOR c_data in cursor
      LOOP
        r := c_data.nbVictoire * 10000;
        IF c_data.nbVictoire > 3
            THEN r := r + 5000;
        END IF;
        IF c_data.nbVictoire > 5
            THEN r := r + 15000;
        END IF;
     
        -- Afficher en table  c_data.nomSkieur, c_data.nbVictoire, r;
     
      END LOOP;
    END;
    $$ LANGUAGE plpgsql;


    Seulement petit problème, imposible de trouver comment renvoyer mes lignes de données pendant la loop de mon curseur.
    J'ai essayé avec différents exemples trouvés sur le net, que se soit avec un Retrun ou un SELECT mais jamais je n'obtient le résultat escompté.

    Comment puis-je faire pour afficher mes résultats ?

  2. #2
    Modérateur

    Bonjour

    Pourquoi passer par un curseur, et même par une fonction ?

    Une simple vue devrait suffire :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    SELECT 
    		nomSkieur
    	,	nbVictoire
    	,	10000 * nbVictoire + CASE
    			WHEN nbVictoire > 5 THEN 20000
    			WHEN nbVictoire > 3 THEN 5000
    			ELSE 0 
    		END AS r
    FROM (
    	SELECT s.noSkieur, s.nomSkieur, COUNT(*) as nbVictoire
        FROM skieur AS s
        INNER JOIN classement as c on c.noSkieur = s.noSkieur
        WHERE c.classement = 1
        GROUP BY s.noSkieur, s.nomSkieur;
    ) AS T

  3. #3
    Nouveau membre du Club
    Je suis tout à fait d'accord, mais mon énoncé stipule de le faire avec une fonction.

  4. #4
    Modérateur

    Soit,

    Alors vous pouvez mettre la requête dans une fonction...

  5. #5
    Nouveau membre du Club
    J'ai récrit le fonction en m'aidant de ceci (https://dba.stackexchange.com/questions/186257/how-can-i-return-multiple-rows-of-records-in-pl-pgsql)

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    CREATE OR REPLACE FUNCTION
    get_rewards_table()
    RETURNS SETOF RECORD AS $$
    DECLARE
      rec RECORD;
    BEGIN
      SELECT 
    		nomSkieur
    	,	nbVictoire
    	,	10000 * nbVictoire + CASE
    			WHEN nbVictoire > 5 THEN 20000
    			WHEN nbVictoire > 3 THEN 5000
    			ELSE 0 
    		END AS prime
      INTO rec  
      FROM (
        SELECT s.noSkieur, s.nomSkieur, COUNT(*) as nbVictoire        FROM skieur AS s
        INNER JOIN classement as c on c.noSkieur = s.noSkieur
        WHERE c.classement = 1
        GROUP BY s.noSkieur, s.nomSkieur
      ) AS T;
      RETURN NEXT rec;
    END;
    $$ LANGUAGE plpgsql;


    Mais j'ia cette erreur:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    BDD=# select get_rewards_table();
    ERREUR:  fonction renvoyant un ensemble appelée dans un contexte qui ne peut pas
    accepter un ensemble
    CONTEXTE : fonction PL/pgsql get_rewards_table(), ligne 20 à RETURN NEXT

  6. #6
    Membre expérimenté
    Bonjour,

    Le lien que vous proposez est très bien : l'avez-vous lu jusqu'à la fin ?

    @Klin dit:
    A better option is to use returns table(...) and return query
    Le savoir est une nourriture qui exige des efforts.

###raw>template_hook.ano_emploi###