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

SQL Oracle Discussion :

[PL/SQL][Oracle9] Retour de curseur avec du Sql dynamique


Sujet :

SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 112
    Points : 62
    Points
    62
    Par défaut [PL/SQL][Oracle9] Retour de curseur avec du Sql dynamique
    Bonjour,

    je dois créer une procédure stockée dynamique qui me retourne en paramètre de sortie un curseur.

    J'ai d'abord fait un test sans Sql dynamique qui fonctionne très bien :
    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 PS_GET_DETAILS_LOCALISATION
    (NOM_TABLE IN VARCHAR2,
    ID_TABLE IN VARCHAR2,
    io_cursor OUT LP_LOCALISATION.C_ST_LOCALISATION )
    AS
    BEGIN
    OPEN io_cursor FOR
    SELECT ID, CODE, DESI FROM VW_LOCALISATION_UP
    WHERE ID = TO_NUMBER(ID_TABLE);
    END;
    Maintenant je souhaite réaliser la même chose avec un nom de vue dynamique :
    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
     
    CREATE OR REPLACE PROCEDURE PS_GET_DETAILS_LOCALISATION
    (NOM_TABLE IN VARCHAR2,
    ID_TABLE IN VARCHAR2,
    io_cursor OUT LP_LOCALISATION.C_ST_LOCALISATION )
    AS
     
    vlStr	VARCHAR2(500) ;
    BEGIN
    vlStr := ' OPEN io_cursor FOR ' ;
    vlStr := vlStr || ' SELECT ID, CODE, DESI ' ;
    vlStr := vlStr || ' FROM VW_LOCALISATION_' || NOM_TABLE ;
    vlStr := vlStr || ' WHERE ID = TO_NUMBER(' || ID_TABLE || ')' ;
     
    ?????????????????
    END;
    Que mettre à la place de ?????
    J'ai essayé un execute immediate, DBMS_SQL.PARSE mais ça ne marche pas j'ai toujours une erreur au moment de l'exécution.
    Merci par avance de votre aide.

  2. #2
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    execute immediate vlStr ;
    non ?

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    ne met pas le "open cursor io_cursor for" dans ta chaine dynamique, il faut faire une open cursor normal mais qui se défini par une chaine dynamique

    voir la doc oracle

    Remarque: Oracle demande à ce qu'une variable curseur soit déclarée en "in out" et non en "out", je vois pas la différence profonde mais soyons bête et discipliné au moins dans un 1ier temps

  4. #4
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 112
    Points : 62
    Points
    62
    Par défaut
    Sorry mais malgré l'aide je ne m'en sors pas, je pense qu'il doit y avoir une grosse erreur de code mais je ne la vois 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
     
    CREATE OR REPLACE PROCEDURE PS_GET_DETAILS_LOCALISATION
    (NOM_TABLE IN VARCHAR2,
    ID_TABLE IN VARCHAR2,
    io_cursor IN OUT LP_LOCALISATION.C_ST_LOCALISATION )
    AS
     
    vlStr	VARCHAR2(500) ;
    BEGIN
    vlStr := 'SELECT ID, CODE, DESI ' ;
    vlStr := vlStr || ' FROM VW_LOCALISATION_' || NOM_TABLE ;
    vlStr := vlStr || ' WHERE ID = TO_NUMBER(' || ID_TABLE || ')' ;
     
    OPEN io_cursor FOR 
    execute immediate vlStr;
     
    END;
    Voici l'erreur de compil
    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
     
    Avertissement : Procédure créée avec erreurs de compilation.
    Erreurs pour PROCEDURE PS_GET_DETAILS_LOCALISATION :
    LINE/COL ERROR
    -------- -----------------------------------------------------------------
    14/9     PLS-00103: Symbole "IMMEDIATE" rencontré à la place d'un des
             symboles suivants :
             . ( * @ % & = - + ; < / > at in is mod not rem
             <an exponent (**)> <> or != or ~= >= <= <> and or like
             between using ||
     
    16/4     PLS-00103: Symbole "end-of-file" rencontré à la place d'un des
             symboles suivants :
             begin function package pragma procedure subtype type use
             <an identifier> <a double-quoted delimited-identifier> form
             current cursor

  5. #5
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Ah ben non, tu as mélangé les 2 posts... et en toute modestie je pense seule ma solution fonctionne...

    il faut faire tout simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
     
    OPEN io_cursor FOR vlStr;
     
    ...
    tu a été voir sur le lien que je t'ai indiqué ?

    http://download-uk.oracle.com/docs/c..._ora.htm#31684

  6. #6
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 112
    Points : 62
    Points
    62
    Par défaut
    Ben en fait j'avais fait pas mal d'essais dont la solution que tu me proposes

    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
     
     
    CREATE OR REPLACE PROCEDURE PS_GET_DETAILS_LOCALISATION
    (NOM_TABLE IN VARCHAR2,
    ID_TABLE IN VARCHAR2,
    io_cursor IN OUT LP_LOCALISATION.C_ST_LOCALISATION )
    AS
     
    vlStr	VARCHAR2(500) ;
    BEGIN
    vlStr := 'SELECT ID, CODE, DESI ' ;
    vlStr := vlStr || ' FROM VW_LOCALISATION_' || NOM_TABLE ;
    vlStr := vlStr || ' WHERE ID = TO_NUMBER(' || ID_TABLE || ')' ;
     
    OPEN io_cursor FOR vlStr;
     
    END;
    mais elle ne marche pas non plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Erreurs pour PROCEDURE PS_GET_DETAILS_LOCALISATION :
     
    LINE/COL ERROR
    -------- -----------------------------------------------------------------
    13/1     PL/SQL: Statement ignored
    13/6     PLS-00455: impossible d'utiliser le curseur 'IO_CURSOR' dans une
             instruction SQL dynamique OPEN
    Je m'arraches les cheveux avec ce problème depuis plusieurs jours et je n'arrive pas à trouver

    J'ai lu le lien indiqué mais visiblement je n'arrive pas à recoller les morceaux

  7. #7
    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
    If faut utiliser une variable REF CURSOR pour ouvriri ce type de curseur dynamique.
    C'est démontré dans la doc pointée par rémi4444
    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

  8. #8
    Membre du Club
    Inscrit en
    Juillet 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 112
    Points : 62
    Points
    62
    Par défaut
    J'ai réussi à créer ma procédure de la façon suivante :

    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 PROCEDURE PS_GET_DETAILS_LOCALISATION
    (NOM_TABLE IN VARCHAR2,
    ID_TABLE IN VARCHAR2,
    IO_CURSOR IN OUT LP_LOCALISATION.C_ST_LOCALISATION )
    AS
     
    TYPE MonCur IS REF CURSOR;
    Cur MonCur;  
     
    vlStr	VARCHAR2(500) ;
    BEGIN
    vlStr := 'SELECT ID, CODE, DESI ' ;
    vlStr := vlStr || ' FROM VW_LOCALISATION_' || NOM_TABLE ;
    vlStr := vlStr || ' WHERE ID = TO_NUMBER(' || ID_TABLE || ')' ;
     
    OPEN Cur FOR vlStr;
     
    END;
    Maintenant la question qui se pose est comment faire pour récupérer le contenu du curseur Cur afin de le faire ressortir (IO_CURSOR IN OUT ) ?

  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
    Utilisez une variable de type SYS_REFCURSOR (au lieur de REF CURSOR). Elle peut être invoquée à l'extérieur de tout package.
    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 du Club
    Inscrit en
    Juillet 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 112
    Points : 62
    Points
    62
    Par défaut
    Merci infiniment cela fonctionne parfaitement, je n'aurai jamais pu y arriver sans votre aide !

    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
     
    CREATE OR REPLACE PROCEDURE PS_GET_DETAILS_LOCALISATION
    (NOM_TABLE IN VARCHAR2,
    ID_TABLE IN VARCHAR2,
    IO_CURSOR IN OUT SYS_REFCURSOR)
    AS
     
    vlStr	VARCHAR2(500) ;
    BEGIN
    vlStr := 'SELECT ID, CODE, DESI ' ;
    vlStr := vlStr || ' FROM VW_LOCALISATION_' || NOM_TABLE ;
    vlStr := vlStr || ' WHERE ID = TO_NUMBER(' || ID_TABLE || ')' ;
     
    OPEN IO_CURSOR FOR vlStr;
     
    END;

  11. #11
    Membre à l'essai
    Inscrit en
    Juillet 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 24
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    mon soucis ce situe à la fin de la réponse.

    en effet, de mon coté j'ai réussi à obtenir le même code.

    Cependant impossible de trouver comment faire pour lire curseur sans connaitre le nom de la table.

    en effet, la quantitée de champ, les champs et les table utilisent ne sont pas connu par la fonction.

    si quelqu'un pouvait m'aider, merci....

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/10/2007, 08h38
  2. Réponses: 2
    Dernier message: 10/05/2007, 14h41
  3. PL/SQL, problème dans un curseur avec un insert
    Par yador dans le forum PL/SQL
    Réponses: 4
    Dernier message: 27/01/2006, 14h31
  4. Procédure stockée avec retour de curseur
    Par Oufti dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 07/11/2005, 22h40
  5. [PL/SQL] Curseur avec Paramètre
    Par blids dans le forum Oracle
    Réponses: 5
    Dernier message: 10/10/2004, 20h07

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