IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Lecture d'un tableau résultant d'une fonction [9.5]


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Septembre 2005
    Messages : 197
    Points : 121
    Points
    121
    Par défaut Lecture d'un tableau résultant d'une fonction
    Bonjour,
    J'ai un petit soucis pour accéder aux valeurs d'un tableau qui provient d'une fonction perso.
    Cette fonction retourne le tableau de données suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0:2]={"{68,3}","{92,1}","{93,7}"}
    Je cherche à lire ces infos dans une autre fonction (fonction de test) :
    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
     
    CREATE OR REPLACE FUNCTION test.stock(p_id_article INTEGER) RETURNS VOID AS $$
    DECLARE
        v_data_stock TEXT[];
        i            SMALLINT;
        v_id_stock   INTEGER;
        v_quantite   INTEGER;
    BEGIN
        SELECT test.verif_stock(p_id_article) INTO v_data_stock;
     
        i = 0;
        WHILE v_data_stock[i] IS NOT NULL LOOP
            v_id_stock = v_data_stock[i][0];
            v_quantite = v_data_stock[i][1];
            RAISE NOTICE 'id_stock=% - quantite_stock=%', v_id_stock, v_quantite;
            i = i + 1;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
     
    SELECT test.stock(4555846);
    Pour le moment les variables v_id_stock et v_quantite restent vide, je ne vois pas trop comment accéder aux éléments {68,3}, {92,1} et {93,7}
    Une idée ?

    Merci

  2. #2
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    L'indice de tableaux commence à 1 avec PostgreSQL. (voir ici paragraphe "8.15.3. Accès aux tableaux")
    Donc, dès le premier pas il obtient null (ou une exception) et il n'exécutera ni le contenu du pas ni aucun pas suivant.
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Septembre 2005
    Messages : 197
    Points : 121
    Points
    121
    Par défaut
    Donc ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    RAISE NOTICE 'v_data_stock=%', v_data_stock[1][1];
    Devrait m'afficher 68 si je prend le 1er élément du 1er tableau de {"{68,3}","{92,1}","{93,7}"}
    Marche pas... La manière de l'écrire n'est pas bonne peut-être ?

  4. #4
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    Donne le code de la fonction tel que tu l'as réécris et dit nous ce qui se passe réellement. "Marche pas ..." n'est pas suffisant pour comprendre le problème!
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Septembre 2005
    Messages : 197
    Points : 121
    Points
    121
    Par défaut
    Oui, avec le code c'est mieux :-)
    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
    CREATE OR REPLACE FUNCTION test.stock(p_id_article INTEGER) RETURNS VOID AS $$
    DECLARE
        v_data_stock TEXT[];
        i            SMALLINT;
        v_id_stock   INTEGER;
        v_quantite   INTEGER;
    BEGIN
        SELECT test.verif_stock(p_id_article) INTO v_data_stock; -- >> retourne ceci : [0:2]={"{68,3}","{92,1}","{93,7}"}
     
        i = 0;
        WHILE v_data_stock[i] IS NOT NULL LOOP
            v_id_stock = v_data_stock[i][1];
            v_quantite = v_data_stock[i][2];
            RAISE NOTICE 'id_stock=% - quantite_stock=%', v_id_stock, v_quantite;
            i = i + 1;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    Petite explication de ce que je cherche à faire :
    je veux retourner en un tableau tous les articles et leur quantité de la table "article.stock" dont l'id = celui fourni en paramètre.
    avec l'exemple donné j'ai 3 lignes dans la table qui correspondent à l'article :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     id | quantite | id_article 
    ----+----------+------------
     68 |        3 |    4555846
     92 |        1 |    4555846
     93 |        7 |    4555846

  6. #6
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    J'ai demandé à avoir le résultat de la fonction stock(integer)!!! Quand tu l'exécute qu'est ce qu'elle donne ou fait réellement???
    Par ailleurs il faut le code de la fonction verif_stock car je ne comprend le format de sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [0:2]={"{68,3}","{92,1}","{93,7}"}
    .
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Septembre 2005
    Messages : 197
    Points : 121
    Points
    121
    Par défaut
    Voilà ce que retourne test.stock() pour l'article dont l'id = 4555846 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    he_livre=# SELECT test.stock(4555846);
    NOTICE:  v_data_stock=[0:2]={"{68,3}","{92,1}","{93,7}"} - id_stock=<NULL> - quantite_stock=<NULL>
    NOTICE:  v_data_stock=[0:2]={"{68,3}","{92,1}","{93,7}"} - id_stock=<NULL> - quantite_stock=<NULL>
    NOTICE:  v_data_stock=[0:2]={"{68,3}","{92,1}","{93,7}"} - id_stock=<NULL> - quantite_stock=<NULL>
     stock 
    -------
     
    (1 ligne)
    Et voici le code de la fonction en question :
    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
    CREATE OR REPLACE FUNCTION test.verif_stock(p_id_article INTEGER) RETURNS TEXT[] AS $$
    DECLARE
        cursor_STOCK                CURSOR FOR SELECT id, quantite FROM article.stock WHERE id_article = p_id_article AND quantite > 0;
        v_id_stock                  INTEGER;
        v_quantite_stock            SMALLINT;
        p_data_stock                TEXT[];
        i                           SMALLINT = 0;
    BEGIN
        OPEN cursor_STOCK;
        LOOP
            FETCH cursor_STOCK INTO v_id_stock, v_quantite_stock;
            EXIT WHEN NOT FOUND;
            p_data_stock[i] = ARRAY[v_id_stock,v_quantite_stock];
            i = i + 1;
        END LOOP;
        CLOSE cursor_STOCK;
        RETURN p_data_stock;
    END;
    $$ LANGUAGE plpgsql;
    Possible que je me sois planté ici ?

  8. #8
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    Dans le code...
    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
    CREATE OR REPLACE FUNCTION test.verif_stock(p_id_article INTEGER) RETURNS TEXT[] AS $$
    DECLARE
        cursor_STOCK                CURSOR FOR SELECT id, quantite FROM article.stock WHERE id_article = p_id_article AND quantite > 0;
        v_id_stock                  INTEGER;
        v_quantite_stock            SMALLINT;
        p_data_stock                TEXT[];
        i                           SMALLINT = 0;
    BEGIN
        OPEN cursor_STOCK;
        LOOP
            FETCH cursor_STOCK INTO v_id_stock, v_quantite_stock;
            EXIT WHEN NOT FOUND;
            p_data_stock[i] = ARRAY[v_id_stock,v_quantite_stock];
            i = i + 1;
        END LOOP;
        CLOSE cursor_STOCK;
        RETURN p_data_stock;
    END;
    $$ LANGUAGE plpgsql;
    • TEXT[] désigne un tableau de TEXT à UNE DIMENSION
    • la ligne [I]p_data_stock = ARRAY[v_id_stock,v_quantite_stock]; place un tableau dans une case , le tableau sera donc converti en text.


    Faisons table rase de tous ces problèmes.
    Peux-tu donner
    • le code des deux fonctions
    • le DDL des tables
    • l'objectif cherché

    Par ailleurs, je soupçonne que vous utilisez le type tableau pour modéliser des lignes de table sql ce qui est TRÈS MAUVAIS!!!
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Septembre 2005
    Messages : 197
    Points : 121
    Points
    121
    Par défaut
    La table est d'une grande simplicité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE article.stock
    (
        id         SERIAL,
        id_article INTEGER NOT NULL DEFAULT 1,
        quantite   SMALLINT NOT NULL DEFAULT 1,
        adresse    SMALLINT NOT NULL DEFAULT 1,
        PRIMARY KEY(id)
    );
    Dans cette table hors de question d'additionner les quantités de plusieurs articles identique car l'adresse en stock est différente pour chaque lignes d'article.

    La première fonction n'a pour but que de me retourner toutes les quantités d'un article recherché ainsi que l'identifiant de ces lignes dans la table "article.stock":
    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
    CREATE OR REPLACE FUNCTION test.verif_stock(p_id_article INTEGER) RETURNS TEXT[] AS $$
    DECLARE
        cursor_STOCK                CURSOR FOR SELECT id, quantite FROM article.stock WHERE id_article = p_id_article AND quantite > 0;
        v_id_stock                  INTEGER;
        v_quantite_stock            SMALLINT;
        p_data_stock                TEXT[];
        i                           SMALLINT = 0;
    BEGIN
        OPEN cursor_STOCK;
        LOOP
            FETCH cursor_STOCK INTO v_id_stock, v_quantite_stock;
            EXIT WHEN NOT FOUND;
            p_data_stock[i] = ARRAY[v_id_stock,v_quantite_stock];
            i = i + 1;
        END LOOP;
        CLOSE cursor_STOCK;
        RETURN p_data_stock;
    END;
    $$ LANGUAGE plpgsql;
    La seconde fonction appel test.verif_stock() qui sera au final utilisée dans plusieurs autres fonctions d'ou la création de cette première fonction.

    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
    CREATE OR REPLACE FUNCTION test.stock(p_id_article INTEGER) RETURNS VOID AS $$
    DECLARE
        v_data_stock TEXT[];
        i            SMALLINT;
        v_id_stock   INTEGER;
        v_quantite   INTEGER;
    BEGIN
        SELECT test.verif_stock(p_id_article) INTO v_data_stock;
     
        i = 0;
        WHILE v_data_stock[i] IS NOT NULL LOOP
            -- C'est ici que ça ne va pas...
            v_id_stock = v_data_stock[i][1];
            v_quantite = v_data_stock[i][2];
            RAISE NOTICE 'id_stock=% - quantite_stock=%', v_id_stock, v_quantite;
            i = i + 1;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    Ce que je cherche à faire : récupérer plusieurs lignes avec la 1ère fonction "test.verif_stock()" et retourner le résultat obtenu à la 2ème fonction "test.stock()" qui effectuera des traitements avec les données ainsi reçue, mais là n'est pas le problème. Je ne vois pas d'autres solutions que de retourner un tableau.

  10. #10
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    Citation Envoyé par Shiva Voir le message
    La première fonction n'a pour but que de me retourner toutes les quantités d'un article recherché ainsi que l'identifiant de ces lignes dans la table "article.stock":
    Éviter les approches des langages procédurales en voulant placer les données SQL dans un tableau.
    Avec les SGBDR ces genres de choses se font UNIQUEMENT avec un SELECT pas une fonction qui retourne un tableau!!!
    A tout instant, lancer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id, quantite FROM article.stock WHERE id_article = p_id_article AND quantite > 0;
    suffira
    A la limite, utilisez une fonction qui renvoie UNE TABLE SQL et non TABLEAU!...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CREATE OR REPLACE FUNCTION test.verif_stock(p_id_article INTEGER) RETURNS table(id integer, quantite SMALLINT)
    AS $$
    SELECT id, quantite FROM article.stock WHERE id_article = p_id_article AND quantite > 0;
    $$ LANGUAGE sql;
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Même une vue suffirait.

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2005
    Messages
    197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Septembre 2005
    Messages : 197
    Points : 121
    Points
    121
    Par défaut
    J'ai opté pour la première solution qui est plus simple et j'ai virer la fonction verif_stock() qui ne sert plus à rien.
    Si je dois rajouter des traitements lors de la vérification de la présence de produit en stock ils seront multipliés autant de fois que ce code est utilisé, mais bon tant pis. En tout cas mon petit soucis est résolu.
    Merci à toi :-)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 13
    Dernier message: 13/10/2006, 00h15
  2. Réponses: 7
    Dernier message: 30/05/2006, 11h09
  3. Réponses: 1
    Dernier message: 18/11/2005, 11h38
  4. Ecrire dans un tableau html depuis une fonction js ?
    Par botanica dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/10/2005, 12h48
  5. passage de tableau 2D a une fonction
    Par watashinoitadakimasu dans le forum C
    Réponses: 2
    Dernier message: 11/09/2003, 02h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo