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 :

[PG/pgsql] Fonction, argument et FROM


Sujet :

Requêtes PostgreSQL

  1. #1
    Invité2
    Invité(e)
    Par défaut [PG/pgsql] Fonction, argument et FROM
    Bonjour,

    Depuis peu j'ai dût m'attaquer aux fonctions, je veux nommer ma table au moment de l'exécution (j'aurais un nombre finit de table), j'ai tenté ça :

    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 FUNCTION ri_ajoute_fils(IN nomtable character, IN nom character, IN pk_parent integer) RETURNS void AS
    $$
    DECLARE
    Bornes RECORD;
    BEGIN
    SELECT BordDroite INTO Bornes FROM nomtable WHERE id=pk_parent;
     
    UPDATE nomtable
    SET BordDroit = BordDroit + 2 
    WHERE BordDroit >= Bornes;
     
    UPDATE nomtable
    SET BordGauche = BordGauche + 2 
    WHERE BordGauche >= Bornes;
     
    INSERT INTO nomtable (BordDroit, BordGauche, nom) 
    VALUES (Bornes, Bornes+1, nom);
    END;
    $$LANGUAGE 'plpgsql' VOLATILE;
    Et donc à l'erreur suivante :

    ERREUR: erreur de syntaxe sur ou près de « $1 »
    LIGNE 1 : SELECT BordDroite FROM $1 WHERE id= $2
    ^
    REQUÊTE : SELECT BordDroite FROM $1 WHERE id= $2
    CONTEXTE : SQL statement in PL/PgSQL function "ri_ajoute_fils" near line 4


    ********** Erreur **********

    ERREUR: erreur de syntaxe sur ou près de « $1 »
    État SQL :42601
    Contexte : SQL statement in PL/PgSQL function "ri_ajoute_fils" near line 4
    Il me semblait que Pl/pgsql permettait les variable à la clause FROM, ai-je mal lu ?

    Par avance merci de votre aide

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    bonjour,il faut utiliser la commande execute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute 'select * from  '|| quote_literal (nom_table)||'...

  3. #3
    jnore
    Invité(e)
    Par défaut
    Attention à mettre des guillemets pour borner les champs qui ont au moins une majuscule !

  4. #4
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    Attention à mettre des guillemets pour borner les champs qui ont au moins une majuscule !
    c'est d'autant plus vrai que je me suis tromper de fonction , il faut utiliiser quote_ident et non quote_literal

  5. #5
    Invité2
    Invité(e)
    Par défaut
    Citation Envoyé par xavier-Pierre Voir le message
    bonjour,il faut utiliser la commande execute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute 'select * from  '|| quote_literal (nom_table)||'...
    Euh, j'ai un léger doute, il me semblait que c'était pour les requêtes préparées, non ?
    Je sais que PL/pgsql prépare ces requêtes, mais ça me parrait bizzard

    Citation Envoyé par jnore Voir le message
    Attention à mettre des guillemets pour borner les champs qui ont au moins une majuscule !
    Je ne comprend pas

    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 FUNCTION ri_ajoute_fils(IN nom_table character, IN nom character, IN pk_parent integer) RETURNS void AS
    '
    DECLARE
    Bornes RECORD;
    BEGIN
    SELECT BordDroite INTO Bornes FROM ''|| quote_indent (nom_table)||'' WHERE id=pk_parent;
     
    UPDATE ''|| quote_indent (nom_table)||''
    SET BordDroit = BordDroit + 2 
    WHERE BordDroit >= Bornes;
     
    UPDATE ''|| quote_indent (nom_table)||''
    SET BordGauche = BordGauche + 2 
    WHERE BordGauche >= Bornes;
     
    INSERT INTO ''|| quote_indent (nom_table)||'' (BordDroit, BordGauche, nom) 
    VALUES (Bornes, Bornes+1, nom);
    END;
    'LANGUAGE plpgsql VOLATILE;
    J'ai tout essayé, avec $$ à la place des ', avec des ' à la place de '', j'ai relu la partie sur les '', je vois pas, quelqu'un pourrait m'envoyer le lien vers la partie qui traite de ça, ou, pourrait m'expliquer, par avance merci de votre aide

  6. #6
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    Euh, j'ai un léger doute, il me semblait que c'était pour les requêtes préparées, non ?
    Je sais que PL/pgsql prépare ces requêtes, mais ça me parrait bizzard
    en tout cas ça marche
    la fonction est quote_ident et non quote_indent
    essaie cette fonction toute simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE OR REPLACE FUNCTION xf_select(ma_table text)
      RETURNS void AS
    $BODY$begin 
    drop view if exists essai_select;
     execute 'create view  essai_select as select * from '|| quote_ident(ma_table);
    return;
    end;$BODY$
      LANGUAGE 'plpgsql'

  7. #7
    Invité2
    Invité(e)
    Par défaut
    Ce code "marche" :

    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 FUNCTION ri_ajoute_fils(IN nom_table character, IN nom character, IN pk_parent integer) RETURNS void AS
    $$
    DECLARE
    Bornes RECORD;
    BEGIN
    EXECUTE 'SELECT BordDroite INTO Bornes FROM '|| quote_indent (nom_table)||' WHERE id=pk_parent;
     
    UPDATE '|| quote_indent (nom_table)||'
    SET BordDroit = BordDroit + 2 
    WHERE BordDroit >= Bornes;
     
    UPDATE '|| quote_indent (nom_table)||'
    SET BordGauche = BordGauche + 2 
    WHERE BordGauche >= Bornes;
     
    INSERT INTO '|| quote_indent (nom_table)||' (BordDroit, BordGauche, nom) 
    VALUES (Bornes, Bornes+1, nom);';
    END;
    $$LANGUAGE 'plpgsql' VOLATILE;
    Ebn revanche, quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * ri_ajoute_fils("ri", "smart", 14);
    J'ai le droit à :
    ERREUR: erreur de syntaxe sur ou près de « ri_ajoute_fils »
    LIGNE 1 : SELECT * ri_ajoute_fils("ri", "smart", 14);
    ^

    ********** Erreur **********

    ERREUR: erreur de syntaxe sur ou près de « ri_ajoute_fils »
    État SQL :42601
    Caractère : 10
    Alors que ma fonction éxiste (lorsque je tente de la re-rentrer il me dit qu'elle éxiste déjà...

    Comment ça se fait qu'elle réxiste pas ?

    par avance merci de votre aide

  8. #8
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    je pense qu'il faut mettre de simples quotes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * ri_ajoute_fils('ri', 'smart', 14);
    par contre il faut peut être doublé lesquotes autour de nom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    execute '...
    INSERT INTO '|| quote_ident (nom_table)||' (BordDroit, BordGauche, '''||nom||''') 
    VALUES (Bornes, Bornes+1,'''||nom||''');';
    c'est quote_ident et pas quote_indent

  9. #9
    Invité2
    Invité(e)
    Par défaut
    J'ai une bonne et une mauvaise nouvelle, la bonne c'est que je vois enfin ma fonction dans la liste, la mauvaise c'est que sont appel me revoit la même erreur, ça viendrait pas du fait que ça doit me renvoyer un void et que je tente de le prendre ?

    Par avance merci de votre aide

  10. #10
    jnore
    Invité(e)
    Par défaut
    Avant le END; tu mets un RETURN TRUE;

  11. #11
    Invité2
    Invité(e)
    Par défaut
    Toujours pareil

    Par avance merci de votre aide

  12. #12
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    pour appeler la fonction on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT  ri_ajoute_fils('ri', 'smart', 14);
    (pas de *)

  13. #13
    Invité2
    Invité(e)
    Par défaut
    Ca marche, du moins, ça appel ma fonction, mais il y a un bug dans ma 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
    20
    21
    22
    CREATE OR REPLACE FUNCTION ri_ajoute_fils(nom_table character, nom character, pk_parent integer)
      RETURNS boolean AS
    $BODY$
    DECLARE
    Bornes RECORD;
    BEGIN
    EXECUTE 'SELECT ''BordDroite'' INTO Bornes FROM '|| quote_ident (nom_table)||' WHERE id='||pk_parent||';';
     
    EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
    SET ''BordDroit'' = ''BordDroit'' + 2 
    WHERE ''BordDroit'' >= Bornes;';
     
    EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
    SET ''BordGauche'' = ''BordGauche'' + 2 
    WHERE ''BordGauche'' >= ''Bornes'';';
     
    EXECUTE 'INSERT INTO '|| quote_ident (nom_table)||' (''BordDroit'', ''BordGauche'', nom) 
    VALUES (Bornes, Bornes+1, '''||nom||''');';
    RETURN TRUE;
    END;
    $BODY$
      LANGUAGE 'plpgsql' VOLATILE;
    Lorsque je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT ri_ajoute_fils('ri', 'smart', 14);
    J'ai le droit à :
    ERREUR: EXECUTE of SELECT ... INTO is not implemented yet
    CONTEXTE : PL/pgSQL function "ri_ajoute_fils" line 4 at EXECUTE statement

    ********** Erreur **********

    ERREUR: EXECUTE of SELECT ... INTO is not implemented yet
    État SQL :0A000
    Contexte : PL/pgSQL function "ri_ajoute_fils" line 4 at EXECUTE statement
    Qu'est-ce que cela signifie ?

    Par avance merci de votre aide

  14. #14
    jnore
    Invité(e)
    Par défaut
    Et si tu essayais ceci sur la ligne 4.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT "BordDroite"  INTO Bornes FROM nom_table
    WHERE id=pk_parent;

  15. #15
    jnore
    Invité(e)
    Par défaut
    Personnellement, je pense que les EXECUTE ne sont pas nécessaires.

    Essaie de les supprimer tous et de ne borner que les champs qui ont au moins une majuscule par des guillemets doubles.

  16. #16
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    bonjour c'est Monsieur "EXECUTE"
    à priori on ne peut pas faire de "SELECT INTO " dans une commande "EXECUTE"
    je te propose de remplacer la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE 'SELECT ''BordDroite'' INTO Bornes FROM '|| quote_ident (nom_table)||' WHERE id='||pk_parent||';';
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    EXECUTE 'create or replace view ma_borne as SELECT ''BordDroite''  FROM '|| quote_ident (nom_table)||' WHERE id='||pk_parent||';';
    select into bornes ''BordDroite'' from ma_borne;
    alors EXECUTION

  17. #17
    Invité2
    Invité(e)
    Par défaut
    Citation Envoyé par jnore Voir le message
    Et si tu essayais ceci sur la ligne 4.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT "BordDroite"  INTO Bornes FROM nom_table
    WHERE id=pk_parent;
    ça me donnera une erreur type "FROM $1", j'avais essayé au début

  18. #18
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    rectification il faut changer la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE 'SELECT ''BordDroite'' INTO Bornes FROM '|| quote_ident (nom_table)||' WHERE id='||pk_parent||';';
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXECUTE 'SELECT ''BordDroite'' FROM '|| quote_ident (nom_table)||' WHERE id='||pk_parent||'' INTO Bornes ;
    de plus je crois que vous confondez la commande EXECUTE EN SQL avec
    EXECUTE EN PL PGSQL

  19. #19
    jnore
    Invité(e)
    Par défaut
    La dernière proposition de Xavier-Pierre a l'air intéressante.
    Chez moi l'écriture suivante fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    EXECUTE 'SELECT "BordDroite" FROM "'|| nom_table ||'" WHERE id= ' || pk_parent || '  INTO Bornes ;
    Comme id est un integer je ne mets pas de guillemets autour de la variable pk_parent.

  20. #20
    Invité2
    Invité(e)
    Par défaut
    Il est vrai que c'est plus simple :


    ERREUR: la colonne « BordDroite » n'existe pas
    LIGNE 1 : SELECT "BordDroite" FROM "ri" WHERE id= 14
    ^
    REQUÊTE : SELECT "BordDroite" FROM "ri" WHERE id= 14
    CONTEXTE : PL/pgSQL function "ri_ajoute_fils" line 4 at EXECUTE statement

    ********** Erreur **********

    ERREUR: la colonne « BordDroite » n'existe pas
    État SQL :42703
    Contexte : PL/pgSQL function "ri_ajoute_fils" line 4 at EXECUTE statement
    Uniquement lorsque je la teste,

    récapitulatif de la 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
    20
    21
    22
    CREATE OR REPLACE FUNCTION ri_ajoute_fils(nom_table character, nom character, pk_parent integer)
      RETURNS boolean AS
    $BODY$
    DECLARE
    Bornes RECORD;
    BEGIN
    EXECUTE 'SELECT "BordDroite" FROM "'|| nom_table ||'" WHERE id= ' || pk_parent || '' INTO Bornes;
     
    EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
    SET ''BordDroit'' = ''BordDroit'' + 2 
    WHERE ''BordDroit'' >= Bornes;';
     
    EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
    SET ''BordGauche'' = ''BordGauche'' + 2 
    WHERE ''BordGauche'' >= ''Bornes'';';
     
    EXECUTE 'INSERT INTO '|| quote_ident (nom_table)||' (''BordDroit'', ''BordGauche'', nom) 
    VALUES (Bornes, Bornes+1, '''||nom||''');';
    RETURN TRUE;
    END;
    $BODY$
      LANGUAGE 'plpgsql' VOLATILE;
    Par avance merci de votre aide

Discussions similaires

  1. Fonction argument d'une autre Fonction
    Par didyeah dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 21/05/2007, 15h10
  2. Appel de fonctions/arguments
    Par GO dans le forum C++
    Réponses: 14
    Dernier message: 25/09/2006, 22h46
  3. [Débutant]Fonction à arguments variables
    Par Jahjouh dans le forum C++
    Réponses: 5
    Dernier message: 14/09/2006, 23h21
  4. Fonction à argument(s) optionnel(s)
    Par JUJU and CO dans le forum C
    Réponses: 3
    Dernier message: 27/01/2006, 11h51
  5. fonction , arguments
    Par molesqualeux dans le forum C
    Réponses: 6
    Dernier message: 31/10/2005, 17h45

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