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

PostgreSQL Discussion :

[Débutant][PgSql] Appel de Procédures InOut


Sujet :

PostgreSQL

  1. #1
    Membre régulier
    Homme Profil pro
    Responsable outils métier VIGS (Veolia)
    Inscrit en
    Septembre 2005
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Responsable outils métier VIGS (Veolia)
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 80
    Points : 87
    Points
    87
    Par défaut [Débutant][PgSql] Appel de Procédures InOut
    Bonjour,

    Débutant sur l'utilisation de PgSql, je reste complètement bloqué sur un simple appel de procédure. Venant du monde Oracle, je pense qu'il me manque quelques concepts clés que je ne suis pourtant pas arrivé à débusquer sur Internet.

    J'ai une simple procédure qui me permet d'ajouter un couple attribut/valeur dans une chaîne de caractères : (j'utilise EMS SQL Manager Lite)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE OR REPLACE FUNCTION "client_sys"."add_to_attr" (name_ varchar, value_ varchar, inout attr_ varchar) RETURNS varchar AS
    $body$
    BEGIN
    	attr_ := attr_||name_||client_sys.getsep('field')||value_||client_sys.getsep('record');    
    END;
    $body$
    LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
    La fonction getsep permet d'obtenir un caract_res de séparation pour les champs et enregistrements. Ces fonctions fonctionnent (testées).

    et une deuxième procédure 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
     
    CREATE OR REPLACE FUNCTION "client_sys"."test" () RETURNS varchar AS
    $body$
    DECLARE
    ess VARCHAR;
    BEGIN
    	ess := 'test123';
        -- Clear de l'attr_
        -- select client_sys.clear_attr(ess);
    	perform client_sys.add_to_attr('essai','toto',ess);
        return ess;
    END;
    $body$
    LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
    A l'exécution de cette procédure, je devrais avoir en sortie le résultat suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Query OK (0,16 sec)
    Return Value: test123Arg1val1
    Or ce n'est pas le cas, j'ai tout simplement le résultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Query OK (0,14 sec)
    Return Value: test123
    En parcourant la documentation, PERFORM semble être l'instruction à utiliser pour exécuter une procédure. A priori, j'ai l'impression qu'elle ignore complètement le résultat en sortie.

    En utilisant l'instruction SELECT, l'exécution sort en erreur (ou la compilation) en demandant une variable pour recevoir le résultat de la fonction.

    Donc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select client_sys.clear_attr(ess) into ess;
    fonctionne. Mais dans ce cas, où est l'intérêt d'utiliser des arguments en INOUT ?

    Voilà l'exposé de mon petit problème qui m'a déjà tout de même joyeusement grignoter deux belles soirées.

    Merci pour votre aide sur ce point, je ne vois plus trop ...

  2. #2
    Membre régulier
    Homme Profil pro
    Responsable outils métier VIGS (Veolia)
    Inscrit en
    Septembre 2005
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Responsable outils métier VIGS (Veolia)
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 80
    Points : 87
    Points
    87
    Par défaut
    Ok, en fait sous postgreSQL, créer une procédure avec un seul argument en INOUT revient à créer une fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE FUNCTION arr(INOUT x varchar[])
     
    est synonyme de 
     
    CREATE FUNCTION arr(x varchar[]) RETURNS varchar[]
    Un post avait été ouvert par un utilisateur de la liste de diffusion postgres.

    Poste de Albe Laurenz - Instaltiating an ARRAY within a function

    Quel est l'intérêt dès lors de créer une procédure avec un seul argument INOUT si Postgres la transforme en fonction ?

  3. #3
    Membre régulier
    Homme Profil pro
    Responsable outils métier VIGS (Veolia)
    Inscrit en
    Septembre 2005
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Responsable outils métier VIGS (Veolia)
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 80
    Points : 87
    Points
    87
    Par défaut
    En fait, mon erreur a été d'utiliser les paramètres OUT et INOUT comme je les utiliserai dans un langage de programmation avec des variables passées en référence.

    PostgreSQL ne sait pas gérer le passage des variables en référence.

    L'utilisation des paramètres IN et INOUT permet d'éviter simplement la déclaration d'un type composite en retour d'une fonction renvoyant plusieurs résultats.

    Ainsi, avant il fallait :
    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
     
    CREATE TYPE inc AS (
      val1 int4,
      val2 int4,
      str  varchar(10));
     
    CREATE FUNCTION incremente_2(valeur int4) RETURNS inc AS
    $$
    DECLARE
    r inc;
    BEGIN
    SELECT INTO r valeur + 1, valeur + 2, 'test';
    RETURN r;
    END
    $$ LANGUAGE plpgsql;
    A présent, avec l'utilisation des paramètres OUT et INOUT :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE FUNCTION incremente81(INOUT int4) AS
    $$
    BEGIN
    $1 = $1 + 1;
    END;
    $$ LANGUAGE plpgsql;
     
    metier=# SELECT incremente81(5);
     incremente81
    ----------------
     6
    (1 ligne)
    ou

    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 FUNCTION incremente81_2(IN valeur int4, OUT val1 int4, OUT val2 int4, OUT str varchar(10)) AS
    $$
    BEGIN
    val1 = valeur + 1;
    val2 = valeur + 2;
    str = 'test';
    END
    $$ LANGUAGE plpgsql;
     
    metier=# SELECT incremente81_2(5);
     incremente
    ------------
     (6,7,test)
    (1 ligne)
     
    metier=# SELECT (incremente81_2(5)).val1;
    val1
    ------
    6
    (1 ligne)

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

Discussions similaires

  1. [MySQL] PHP.PDO Appel d’une procédure stockée MYSQL avec arguments IN, OUT et INOUT
    Par Depite dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 27/03/2015, 10h20
  2. [débutant] appel de procédure stockée
    Par Jonkile dans le forum PL/SQL
    Réponses: 3
    Dernier message: 08/04/2009, 17h48
  3. Réponses: 1
    Dernier message: 14/08/2007, 11h14
  4. [c#] débutant Winform - Appel de procédure
    Par jpo dans le forum Windows Forms
    Réponses: 2
    Dernier message: 13/07/2007, 16h51
  5. Débutant, appel de procédure
    Par webtheque dans le forum Oracle
    Réponses: 1
    Dernier message: 18/09/2006, 18h30

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