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 :

Transformer en procédure qui retourne un curseur


Sujet :

PL/SQL Oracle

  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut Transformer en procédure qui retourne un curseur
    Bonjour

    Comment transformer ce bloc anonyme avec un procédure qui retourne le curseur (d'une jointure). ?

    Je n'y arrive pas j'ai toujours l'erreur
    PLS-00320: the declaration of the type of this expression is incomplete or malformed
    J'ai essayé plusieurs types dont sys_refcursor.

    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
    23
    24
    25
    26
    27
    28
    SET SERVEROUTPUT ON SIZE 1000000;
    DECLARE
      -- declare a cursor
      CURSOR cur_chief IS
          SELECT first_name,
                 last_name,
                 department_name
          FROM employees e
          INNER JOIN departments d ON d.manager_id = e.employee_id;
     
      r_chief cur_chief%ROWTYPE;
    BEGIN
      OPEN cur_chief;
      LOOP
        -- fetch information from cursor into record
        FETCH cur_chief INTO r_chief;
     
        EXIT WHEN cur_chief%NOTFOUND;
     
        -- print department - chief
        DBMS_OUTPUT.PUT_LINE(r_chief.department_name || ' - ' ||
                             r_chief.first_name || ',' ||
                             r_chief.last_name);
      END LOOP;
      -- close cursor cur_chief
      CLOSE cur_chief;
    END;
    /
    merci

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2008
    Messages : 23
    Par défaut
    je crois que j'ai exactement le même problème et le mien il me dit invalid cursor exactement lorsque je veux vérifier que le curseur contient ecore des données plus précisément sur la ligne EXIT WHEN curseur%NOTFOUND...

    Si quelqu'un a une idée.

    Merci

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut mon code transformé
    J'ai le code suivant :

    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
    23
    24
    25
    26
    27
    create or replace PROCEDURE getCursor(p_recordset OUT SYS_REFCURSOR )
    IS 
    begin
      OPEN p_recordset FOR
          SELECT first_name,
                 last_name,
                 department_name
          FROM employees e
          INNER JOIN departments d ON d.manager_id = e.employee_id;
    end;
    /
    DECLARE
      cur_chief SYS_REFCURSOR;
      r_chief cur_chief%ROWTYPE;
     
    BEGIN
      getCursor(cur_chief);
      LOOP
        FETCH cur_chief INTO r_chief;
        EXIT WHEN cur_chief%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(r_chief.department_name || ' - ' ||
                             r_chief.first_name || ',' ||
                             r_chief.last_name);
      END LOOP;
      CLOSE cur_chief;
    END;
    /
    et la sortie :

    Elément PROCEDURE GETCURSOR compilé
    ....
    Rapport d'erreur -
    ORA-06550: line 3, column 11:
    PLS-00320: the declaration of the type of this expression is incomplete or malformed
    ORA-06550: line 3, column 11:
    je pense que le probleme vient de la ligne :
    cur_chief SYS_REFCURSOR;
    mais en essayant les types j'ai aussi des erreurs....

    Quelqu'un aurait des idées ?
    Si un aficionados du PL-SQL passait pas la ...

  4. #4
    Expert confirmé 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
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
    Connected as mni
     
    SQL> set serveroutput on
    SQL> 
    SQL> CREATE OR REPLACE PROCEDURE getCursor(p_recordset OUT SYS_REFCURSOR )
      2  IS
      3  begin
      4    OPEN p_recordset FOR
      5        SELECT first_name,
      6               last_name,
      7               department_name
      8        FROM employees e
      9        INNER JOIN departments d ON d.manager_id = e.employee_id;
     10  end;
     11  /
     
    Procedure created
     
    SQL> 
    SQL> DECLARE
      2    cur_chief   SYS_REFCURSOR;
      3    Type r_chief  Is Record (
      4      first_name          hr.employees.first_name%type,
      5      last_name           hr.employees.last_name%type,
      6      department_name     hr.departments.department_name%type
      7    );
      8    var_chief             r_chief;
      9  BEGIN
     10    getCursor(cur_chief);
     11    LOOP
     12      FETCH cur_chief INTO var_chief;
     13      EXIT WHEN cur_chief%NOTFOUND;
     14      DBMS_OUTPUT.PUT_LINE(var_chief.department_name || ' - ' ||
     15                           var_chief.first_name || ',' ||
     16                           var_chief.last_name);
     17    END LOOP;
     18    CLOSE cur_chief;
     19  END;
     20  /
     
    Executive - Steven,King
    IT - Alexander,Hunold
    Finance - Nancy,Greenberg
    Purchasing - Den,Raphaely
    Shipping - Adam,Fripp
    Sales - John,Russell
    Administration - Jennifer,Whalen
    Marketing - Michael,Hartstein
    Human Resources - Susan,Mavris
    Public Relations - Hermann,Baer
    Accounting - Shelley,Higgins
     
    PL/SQL procedure successfully completed
     
    SQL>
    C'est quoi votre problème ?

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut RECORD
    He bien voila ...
    la dernier chose que je n'avais pas testé... et que je viens de faire...
    et reconfirmer mnitu : IL FAUT PASSER PAR UN RECORD !
    mais pourquoi ? est ce la seule solution ?

    Disons que tout reecrire les champs et type ca me dit pas trop...
    impossible d'avoir une solution comme ROWTYPE ...? ou un curseur plus global ???

    J'en profite pour demander s'il faut mieux passer par une procedure ou un fonction ? des diffrences de performance ?
    merci mnitu

  6. #6
    Expert confirmé 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
    Par défaut
    Citation Envoyé par aspire Voir le message
    ...
    Disons que tout reecrire les champs et type ca me dit pas trop...
    impossible d'avoir une solution comme ROWTYPE ...? ou un curseur plus global ???
    ...
    Analysez votre exemple :
    Vous déclarez une variable de type curseur faible (cur_chief) c’est-à-dire un pointer vers une région de mémoire ou se « trouvera » une structure de données actuellement indéfinie.

    Après vous déclarez une variable de type record (r_chief) et pour les détails du record vous faite pointer vers la variable pointer (cur_chief) qui pointe elle-même vers une zoné de mémoire de la structure non-définie.

    Maintenant imaginez-vous que vous est le compilateur et que vous devez résoudre la définition de la variable r_chief et donc expliciter sa structure.
    N’est pas vrai que la vie est merdique ?

  7. #7
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut VDM et indéfini et néant
    Ha l'indéfinie et ses charmes ...

    J'avais un tant soit peu espéré dans un fol élan qu'on pouvait retrouver la structure de la jointure...
    J'ai vu des post ou il parlait de table temporaire créer pour l'occasion et de faire pointer le curseur dessus.
    Est ce réalisable ?
    ca me parait pas tres optimum en perf.
    mais bon sait-on jamais.
    Est ce la seule façon de faire pour récupérer les donneur d'un curseur de jointure ?

    sinon ouais on peut avoir une VDM mais bon réservons ca au pl-sql...

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2008
    Messages : 23
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    getCursor(cur_chief);
     11    LOOP
     12      FETCH cur_chief INTO var_chief;
     13      EXIT WHEN cur_chief%NOTFOUND;
     14      DBMS_OUTPUT.PUT_LINE(var_chief.department_name || ' - ' ||
     15                           var_chief.first_name || ',' ||
     16                           var_chief.last_name);
     17    END LOOP;
     18    CLOSE cur_chief;
    En analysant cette partie, penses tu qu'il devrait planter.? Moi c'est à peu près ce que j'ai ecrit mais lorsqu'il arrive à la ligne 13, il plante en me disant INVALID CURSOR. Quel serait le problème dans ce cas?

  9. #9
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 79
    Par défaut
    A premier vue comme ca je dirais qu'il faut un
    SYS_refCursor pour le passage d'un curseur en parametre IN ou OUT de procedure....
    try this

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/11/2012, 16h18
  2. Fonction qui retourne un curseur
    Par satrucci dans le forum Oracle
    Réponses: 2
    Dernier message: 01/07/2011, 13h31
  3. une procédure qui retourne une valeur ?
    Par Jcpan dans le forum Débuter
    Réponses: 8
    Dernier message: 31/03/2010, 19h02
  4. Réponses: 3
    Dernier message: 14/09/2006, 08h44
  5. Procedure stockée qui retourne un curseur
    Par kinaï dans le forum Débuter
    Réponses: 1
    Dernier message: 10/08/2004, 14h42

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