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

PL/SQL Oracle Discussion :

Appeler dynamiquement des procédures stockées


Sujet :

PL/SQL Oracle

  1. #1
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut Appeler dynamiquement des procédures stockées
    Salut
    Je développe une procédure stockée dans laquelle je veut appeler des autres procédures ou fonction dont les noms sont stockés dans une base de données.
    Comment je peut appeler dynamiquement ces procédures ?

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Avec EXECUTE IMMEDIATE.

    Conseil afin d'éviter les posts d'erreurs : Quand on développe, toujours afficher par DBMS_OUTPUT la chaine de caractère qui va être exécutée par le Execute Immediate. Quand c'est bon, on l'enlève.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par McM Voir le message
    Avec EXECUTE IMMEDIATE.

    Conseil afin d'éviter les posts d'erreurs : Quand on développe, toujours afficher par DBMS_OUTPUT la chaine de caractère qui va être exécutée par le Execute Immediate. Quand c'est bon, on l'enlève.
    Merci McM pour la réponse,
    J'ai déjà travaillé avec EXECUTE IMMEDIATE pour des requêtes sql.Mais est ce que je peut l'utilisé pour l'appel d'une fonction ,si oui comment faire et comment je puisse recupérer alors le resultat de mon fonction(je suppose que toutes mes fonctions retourne un boolean)

  4. #4
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Create or Replace Function f1()
    return number is
    ...
    End;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Declare
      n number ;
    Begin
      EXECUTE IMMEDIATE 'Select f1 from dual' INTO n ;
    End;
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  5. #5
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Je ferrais plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    declare
      l_num pls_integer;
    begin
      execute immediate 'begin :n := f(); end;' Using Out l_num;
      --
      dbms_output.put_line(l_num);
    end;

  6. #6
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    les 2 fonctionnent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      1  DECLARE
      2   n  NUMBER ;
      3  Begin
      4    EXECUTE IMMEDIATE 'Select ff1 from dual' INTO n ;
      5    dbms_output.put_line('n:' || n);
      6* END;
    SQL> /
    n:1
    Procédure PL/SQL terminée avec succès.
    SQL>
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  7. #7
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par SheikYerbouti Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Create or Replace Function f1()
    return number is
    ...
    End;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Declare
      n number ;
    Begin
      EXECUTE IMMEDIATE 'Select f1 from dual' INTO n ;
    End;
    Merci SheikYerbouti pou votre aide ,
    j'ai testé votre proposition avec une procedure stocké test_code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     test_code('2742337') from dual
    mais ma procédure n'est pas appelé et j'ai une erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    java.sql.SQLException: ORA-00904: "test_code" : identificateur non valide

  8. #8
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Merci SheikYerbouti pou votre aide ,
    j'ai testé votre proposition avec une procedure stocké test_code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select test_code('2742337') from dual
    mais ma procédure n'est pas appelé et j'ai une erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    java.sql.SQLException: ORA-00904: "test_code" : identificateur non valide

  9. #9
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    ?? mais vous voyez bien, dans l'example qu'il faut utiliser EXECUTE IMMEDIATE.

    Si vous ne donnez pas le code exact est complet que vous testez, on ne peut pas le deviner...
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  10. #10
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par SheikYerbouti Voir le message
    ?? mais vous voyez bien, dans l'example qu'il faut utiliser EXECUTE IMMEDIATE.

    Si vous ne donnez pas le code exact est complet que vous testez, on ne peut pas le deviner...
    Désolé de ne pas vous donner tout le code car il s'agit d'une trés grande procédure, mais je veut essayer de resumer:
    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
     
    CURSOR curs_contl  IS SELECT *  FROM PARAM_CONTROL    WHERE  ACTIF='1' ;
    FOR contl IN curs_contl 
      LOOP
          BEGIN
     
    if(contl.proc_stc is not null) THEN
             BEGIN
                  v_execute_procedure:= 'select '|| contl.proc_stc ||'('''||P_COD_MES_INT||''') from dual';
                 INSERT INTO trace_table VALUES(v_execute_procedure,'hhh');commit;
                 execute immediate (v_execute_procedure);
                 EXception WHEN OTHERS THEN
                   INSERT INTO trace_table VALUES('error appel procedure','nnnnnnnnnn');commit;
             END;
    ...

  11. #11
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    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
    SQL> create function fx1(n IN number) return number is begin return n; end;
      2  /
     
    Function created.
    SQL> set serveroutput on
    SQL> Declare
      2    func varchar2(20) := 'fx1(:1)';
      3    req varchar2(1000);
      4    n    number := 123 ;
      5  Begin
      6    req := 'select ' || replace(func,':1',n) || ' from dual ' ;
      7    execute immediate req into n ;
      8    dbms_output.put_line('n:' || n);
      9  End;  
     10  /
    n:123
     
    PL/SQL procedure successfully completed.
     
    SQL>
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  12. #12
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    ... mais je suis d'accord avec Mnitu sur le fait que dans le cas d'une procédure au lieu d'une fonction, sa syntaxe est obligatoire
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  13. #13
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par SheikYerbouti Voir le message
    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
    SQL> create function fx1(n IN number) return number is begin return n; end;
      2  /
     
    Function created.
    SQL> set serveroutput on
    SQL> Declare
      2    func varchar2(20) := 'fx1(:1)';
      3    req varchar2(1000);
      4    n    number := 123 ;
      5  Begin
      6    req := 'select ' || replace(func,':1',n) || ' from dual ' ;
      7    execute immediate req into n ;
      8    dbms_output.put_line('n:' || n);
      9  End;  
     10  /
    n:123
     
    PL/SQL procedure successfully completed.
     
    SQL>
    Merci SheikYerbouti,
    Dans cet exemple tu suppose appeler une fonction.Mais je veut appeler des procédures ,j'ai testé votre code et j'ai une erreure:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE OR REPLACE PROCEDURE "TEST_TY" AS
     
    func varchar2(20) := 'TEST(:1)';
    req varchar2(1000);
    BEGIN
     
      req := 'select ' || replace(func,':1','tftftff') || ' from dual ' ;
        execute immediate req  ;
       -- dbms_output.put_line('n:' || n);
     
    END TEST_TY;
    voici l'erreure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ORA-00904: "TEST" : identificateur non valide
    avec TEST est le nom de la procédure que je veut appeler

  14. #14
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Comme je le disais juste avant, dans le cas d'une procédure, il faut utiliser la syntaxe donnée par Mnitu en début de file.
    Sinon, depuis le début vous ne parliez que de fontion retournant un booleen...
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  15. #15
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Petit remarque : une fonction qui retourne un boolean ne peut pas être appelée dans une construction de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Select f()
       Into l_var
       From dual
    /
    le type boolean étant inconnue par le moteur SQL.

  16. #16
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Petit remarque : une fonction qui retourne un boolean ne peut pas être appelée dans une construction de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Select f()
       Into l_var
       From dual
    /
    le type boolean étant inconnue par le moteur SQL.
    J'ai réussit à appeler dynamiquement mes procédures stockés;
    voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     v_execute_procedure:='BEGIN'||contl.proc_stc||'(:codMessage); END;';
     execute immediate v_execute_procedure   using CODE_MESSAGE;
    sauf que maintenant,j'ai ajoutés à mes procédures que j'appele un paramètre IN OUT ,j(obtient ainsi des message d'erreurs:
    j'ai essayé une premiére solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    RESULT number;
    ...
    v_execute_procedure:='BEGIN'||contl.proc_stc||'(:codMessage,:RESULT); END;';
     execute immediate v_execute_procedure   using CODE_MESSAGE,RESULT;
    j'obtient l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Cause: java.sql.SQLException: ORA-06536: variable attachée (bind variable) IN liée à une position OUT
    alors je me suis passé du binding dans le paramètre IN OUT et j'ai essayé une deuxième méthode mais toujouirs sans reussir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    RESULT number;
    ...
    v_execute_procedure:='BEGIN'||contl.proc_stc||'(:codMessage,'||RESULT||'); END;';
     execute immediate v_execute_procedure   using CODE_MESSAGE;
    voici l'erreur que j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Cause: java.sql.SQLException: ORA-06550: Ligne 1, colonne 30 :
    PLS-00103: Symbole ")" rencontré à la place d'un des symboles suivants :
     
       ( - + case mod new not null others <identificateur>
       <identificateur entre guillemets> <variable bind> avg count
       current exists max min prior sql stddev sum variance execute
       forall merge time timestamp interval date
       <un littéral de chaîne avec spécification de jeu de caractères>
       <un nombre> <une chaîne SQL entre apostrophes> pipe
       <constante de chaîne éventuellement entre guillemets avec indication du jeu de caract
    comment je puisse faire?

  17. #17
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Tu as un tuto sur le site pour le Execute Immediate.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     USING IN CODE_MESSAGE, OUT RESULT;
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  18. #18
    Expert éminent sénior
    Avatar de SheikYerbouti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    6 760
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 6 760
    Points : 11 862
    Points
    11 862
    Par défaut
    Mettez au moins un espace derrière le BEGIN...
    Rédacteur Oracle (Oracle ACE)
    Guide Oracle ,Guide PL/SQL, Guide Forms 9i/10g, Index de recherche
    Je ne réponds pas aux questions techniques par MP
    Blogs: Forms-PL/SQL-J2EE - Forms Java Beans

  19. #19
    Membre régulier
    Inscrit en
    Février 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 686
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par McM Voir le message
    Tu as un tuto sur le site pour le Execute Immediate.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     USING IN CODE_MESSAGE, OUT RESULT;
    Merci McM,
    ça marche parfaitement maintenant

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

Discussions similaires

  1. Appel des procédures stockées en C++
    Par emmye dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 28/02/2012, 00h19
  2. Appel d'une procédure stockée ayant des arguments de type TABLE despuis du code C#
    Par rabddoul dans le forum Interfaces de programmation
    Réponses: 3
    Dernier message: 23/10/2008, 10h47
  3. [Pro*C] Appel dynamique à une procédure stockée
    Par wedgeantilles dans le forum Interfaces de programmation
    Réponses: 3
    Dernier message: 22/10/2008, 09h19
  4. Réponses: 1
    Dernier message: 22/11/2006, 17h38
  5. Appeler dynamiquement une procédure stockée
    Par Mark531 dans le forum Access
    Réponses: 1
    Dernier message: 05/09/2006, 17h49

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