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 :

Initialiser une variable curseur avec fonction renvoyant un curseur


Sujet :

PL/SQL Oracle

  1. #1
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut Initialiser une variable curseur avec fonction renvoyant un curseur
    Bonjour, je précise que je débute complètement en PL/SQL (sans formation qui plus est...)
    J'ai créé une fonction qui renvoie un curseur (pour faire un pivot). Mais voilà, dans ma procédure je ne vois pas trop comment initialiser une variable curseur à partir de cette fonction. En effet, jusqu'alors je faisais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OPEN monCurseur FOR maRequeteString;
    Je suppose qu'on ne peut pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monCurseur := maFonction('maTable');
    Merci d'avance pour vos réponses

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    A tout hasard, la syntaxe ce serait pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OPEN  maFonction('maTable');
    ?

  3. #3
    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
    Laissez le hasard pour la théorie du chaos et lisez un peu la documentation d’Oracle sur les variables curseur.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    Merci mais où puis-je trouver cette documentation. Désolé mais les gens avec qui je travaille m'ont d'aller voir sur metalink mais je n'ai pas de comtpe Je suis en formation en alternance et j'apprends sur le tas sans vraiment de support

    EDIT : peut-être là ? http://www.oracle.com/technetwork/in...ion/index.html

  5. #5
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Toute la doc Oracle sur http://tahiti.oracle.com

    Ensuite si vous êtes un débutant complet, peut-être qu'affecter le résultat d'une fonction à un curseur n'est pas la chose à apprendre prioritairement

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    Merci pour le lien Je vais y jeter aussi un coup d'oeil.
    Pour les bases du PL/SQL, j'ai déjà lu :
    http://fr.scribd.com/doc/56704422/Oracle-Plsql
    et
    http://sheikyerbouti.developpez.com/pl_sql/

    Je ne suis pas un débutant en programmation donc pour les bases y'a pas de problèmes J'ai déjà développé 2/3 packages avec des curseurs mais vraiment tout simples sans aucun problème.
    Là c'est que je dois développer un traitement plutôt lourd qui manipule des données dans tous les sens. Les infos sont difficiles à trouver sur Internet et apparemment la communauté Oracle est beaucoup moins présente pour aider ceux qui débutent....contrairement à d'autres communautés qui m'ont vraiment aidé.

    Ma question me paraissait pourtant simple...

    Cordialement

    EDIT : ça fait déjà 3h que je cherche une réponse à cette question....Je crois qu'il va m'en falloir 3 autres pour trouver la réponse dans la doc....Il faudrait déjà être formé à utiliser la doc !

  7. #7
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597

  8. #8
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    Merci pour ce lien mais ce n'est pas ce que je cherchais. Je pense avoir trouvé une solution. Par contre ma fonction me renvoie un curseur avec un nombre de colonnes qui n'est pas fixe (analyse croisée). Donc maintenant je cherche comment parcourir ce curseur au nombre de colonnes variable...

    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
    DECLARE
        myCursor    sys_refcursor;
     
    begin
        SELECT pivot_func('APPS.DRPA_RESCHEDULING_ACTUALS_V','period','MON-YYYY','forecast',
                      'PROJECT_NUMBER',
                      'TASK_NUMBER',
                      'DEPARTMENT_NAME',
                      'ACTUALS',
                      'DELTA',
                      'SUMFORECAST',
                      'NBMONTHS') INTO myCursor FROM DUAL;
     
                LOOP
                    FETCH myCursor INTO --Bah là je suis coincé puisque le nbre de colonnes est variable;
     
                    EXIT WHEN myCursor%NOTFOUND;
     
                END LOOP;
             CLOSE myCursor;         
    end;
    EDIT : c'est possible de créer un type RECORD dynamique ? ou du moins avec 40 champs par exemple et quand des champs ne sont pas utilisés par le FETCH de mettre une valeur NULL par défaut ? J'ai essayé mais ça n'a pas l'air de marcher

  9. #9
    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
    Remarque : c’est plus efficace de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Variable := function() ;
    Quelle est votre version d’Oracle ? Que est-ce qu’elle fait précisement votre fonction pivot ?

    En attendant:
    • Il y a une fonction pivot dans Oracle à partir de la version 11g donc pas besoin d’une autre procédure.
    • Nombre des colonnes variables vaut SQL Dynamique méthode 4 pour lequel il y a des solutions basées soit sur le package DBMS_SQL soit sur le type ANYDATA TYPE.

  10. #10
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    A un moment je m'étais penché sur le sujet et j'ai accouché d'une usine à gaz :

    http://ojo-blog.blogspot.fr/2011/01/...-et-plsql.html

    Si vous aimez faire souffrir mille morts à de pauvres diptères ça doit pouvoir s'adapter à votre problème.

  11. #11
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    Mnitu :J'avais essayé hier de faire maVariable := maFonction(); mais ça ne marchait pas !!!! Et ce matin, ça marche...Moi pas comprendre lol :p
    (encore des heures de perdues pour sûrement un point-virgule ou une parenthèse manquante....)

    Ma version d'Oracle est en 11G et reconnaît donc l'instruction PIVOT.....IN.... qui est utilisée par ma fonction. Je l'ai créée car il est apparemment impossible de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM maVue
    PIVOT (SUM(quantity) FOR period IN (SELECT DISTINT period from maVue))
    En effet, je ne connais pas à l'avance le nombre de colonnes.
    Donc la fonction construit la clause IN et renvoit le résultat de ma requête analyse croisée sous forme d'un curseur. Puis, à la demande d'un collègue, j'ai rendu adaptable cette fonction (nombre d'en-têtes de lignes variables, type d'en-tête de colonnes variable,etc.).
    J'obtiens bien le résultat attendu mais maintenant il faut que je parcours ce curseur pour y effectuer mon traitement et l'écrire dans un fichier Excel. Ce qui me bloque c'est donc comment parcourir un curseur dont le nombre de colonnes peut être connu mais variable....

    ojo77 : Merci pour votre lien, je vais faire travailler ma ptite cervelle pour essayer de comprendre votre article.

    EDIT : si je comprends bien, ojo77, vous créez une procédure dynamique par programmation ?

    PS : c'est la première fois que je vois qqun utiliser le vouvoiement sur un forum (même sur DVP.com :p)

  12. #12
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Oui c'est ça. Je crée ma procédure à la volée en fonction du nombre de colonnes à sortir.

    Il doit y avoir plus simple

  13. #13
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    C'est une bonne idée et je la garde sous le coude (je ne maîtrise pas encore ce type de procédure et je ne suis pas sûr qu'on puisse le faire ici. donc je vais éviter de perdre du temps à essayer d'y arriver)
    En fait un collègue m'a donné un exemple de requête avec des CASE WHEN permettant d'avoir un nombre de colonnes fixe (fonctionnellement, nous sommes limités à 40 colonnes max de toute manière). L'intitulé des colonnes étant COL_01, COL_02, COL_3....en stockant le mois de début et de fin pour chaque enregistrement, on va pouvoir arriver à reconstituer le nom de chaque colonne

    Je reviens donner des nouvelles

  14. #14
    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
    Apparement votre exemple pourrait fonctionner avec la clause XML mais bon.
    Comme je vous l'ai déjà dit
    Nombre des colonnes variables vaut SQL Dynamique méthode 4 pour lequel il y a des solutions basées soit sur le package DBMS_SQL soit sur le type ANYDATA TYPE.
    Concernant le ANYDATA TYPE :
    Voilà un lien: Dynamic number of columns qui pointe vers un autre lien.
    Un autre example: method 4 dynamic sql in pl/sql
    Pour DBMS_SQL regardez dans la doc.

  15. #15
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    Merci mnitu pour ces éléments que je ne manquerai pas de regarder dès que j'aurai le temps. Cela m'a l'air très intéressant. Comme je l'ai dit, je me lance dans la méthode citée ci-dessus, à savoir "avoir un nombre de colonnes fixes" quitte à avoir des champs NULL.

    Voici donc un exemple :
    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
    SELECT project_number,
           actuals,
           delta,
           sumforecast,
           nbmonths,
           dateDebut,
           dateFin,
           SUM(COL_01) COL_1,
           SUM(COL_02) COL_02,
           SUM(COL_03) COL_03,
    	   ....
           SUM(COL_40) COL_40
    FROM (
    SELECT temp.project_number,
           temp.actuals,
           temp.delta,
           temp.sumforecast,
           temp.nbmonths,
           temp.beginning,
           temp.end,
            case when diff = 0 then temp.forecast else NULL end COL_01,
            case when diff = 1 then temp.forecast else NULL end COL_02,
            case when diff = 2 then temp.forecast else NULL end COL_03,
    		....
            case when diff = 39 then temp.forecast else NULL end COL_40
    FROM (SELECT maVue.*,
                 MONTHS_BETWEEN(TO_DATE(maVue.period,'MON-YYYY','NLS_DATE_LANGUAGE = AMERICAN'), maVue.dateDebut) diff
          FROM maVue) temp)
    GROUP BY project_number,
             actuals,
             delta,
             sumforecast,
             nbmonths,
             dateDebut,
             dateFin
    Ce qui m'évite de faire un PIVOT avec ma fameuse fonction et d'avoir un nombre de colonnes fixe. En gros cela ressemble à ce qu'il se faisait apparemment avant la version 11g avec la fonction DECODE.

    PS : en relisant le topic en entier, vous auriez tous pu me dire que j'avais tort d'écrire :
    Citation Envoyé par Paidge
    Je suppose qu'on ne peut pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monCurseur := maFonction('maTable');
    j'aurais gagné quelques heures de travail

  16. #16
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2010
    Messages
    801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 801
    Points : 1 107
    Points
    1 107
    Par défaut
    Ma méthode fonctionne bien Merci à tous !

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

Discussions similaires

  1. initialiser une variable session avec javascript
    Par mvc_dev dans le forum ASP.NET
    Réponses: 12
    Dernier message: 14/12/2017, 14h07
  2. Problème avec fonction renvoyant une "Nested Table"
    Par Sunchaser dans le forum PL/SQL
    Réponses: 4
    Dernier message: 20/05/2009, 17h19
  3. initialiser une variable avec de l'hexadecimale
    Par dietrich dans le forum VB.NET
    Réponses: 1
    Dernier message: 12/01/2007, 10h21
  4. Réponses: 4
    Dernier message: 19/04/2006, 16h03
  5. Réponses: 9
    Dernier message: 29/06/2004, 08h40

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