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 :

curseur et dbms_output.put_line


Sujet :

SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut curseur et dbms_output.put_line
    Bonjour j'essaie d'afficher les résultats d'une requête en découpant les résultats en 3 (avec le LIMIT 3) mais visiblement le buffer est plein... je ne comprend pas pourquoi si on affiche 3 par 3 les résultats, cela devrait marcher et ne pas remplir le buffer ?

    Voici mon code :

    set serveroutput on 1000000;

    declare

    Cursor cur is SELECT distinct DOSSIER_GED.NO_DOS_GED from
    DOSSIER_GED, CHANGEMENT_ETAT_DOS_GED
    where DOSSIER_GED.NO_DOS_GED = CHANGEMENT_ETAT_DOS_GED.NO_DOS_GED;

    TYPE TYP_TAB_NODOSGED IS TABLE OF DOSSIER_GED.NO_DOS_GED%Type;

    Temp_no_dos_ged TYP_TAB_NODOSGED;

    Pass pls_integer := 1;

    begin

    OPEN cur;

    LOOP

    FETCH cur BULK COLLECT into Temp_no_dos_ged LIMIT 3;

    FOR i In Temp_no_dos_ged.first..Temp_no_dos_ged.last LOOP

    dbms_output.put_line(Pass || ' Test de : ' ||
    Temp_no_dos_ged(i));

    END LOOP;

    Pass := Pass + 1;

    Exit when cur%NOTFOUND;

    END LOOP;

    CLOSE cur;

    rollback;
    end;

  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 : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    c'est quoi l'erreur exactement ? Sinon, le buffer est de 1000000 de caractères peu importe qu'ils arrivent pas paquet de 3 ou de 10000

  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
    Citation Envoyé par vincent_17 Voir le message
    Bonjour j'essaie d'afficher les résultats d'une requête en découpant les résultats en 3 (avec le LIMIT 3) mais visiblement le buffer est plein... je ne comprend pas pourquoi si on affiche 3 par 3 les résultats, cela devrait marcher et ne pas remplir le buffer ?

    Voici mon code :
    Parce que c'est un buffer et non pas un print(f). Donc tes données s'accumulent dans le buffer jusqu'au moment ou soit:
    • le buffer se vide
    • le buffer est plein ce qui doit provoquer une erreur


    Inutile de dire que tu ne peut pas forcer le vidage de buffer avec un sort de flush
    Donc utilise UTL_FILE pour écrire dans un fichier ou bien une autre méthode.

  4. #4
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    Bonjour,

    Merci pour vos réponses.

    Je pensais qu'on pouvait soulager le buffer par le BULK COLLECT (d'ailleurs à quoi sert-il dans ces cas là ?) en affichant par paquet mais effectivement je crois que ce qui compte c'est la taille globale du buffer, il se remplit avec toutes les données, c'est exactement ce que je ne voulais pas.

    Un printf() aurait été idéal dans cette situation.

    Le problème est que je ne peux pas passer par un fichier, l'architecture actuelle ne le permet pas, comment je peux faire par une autre méthode ?

    Je n'ai pas très bien saisi ce concept ?
    Qu'est-ce que cela va changer par une autre méthode ?

    Merci d'avance.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    500
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 500
    Points : 639
    Points
    639
    Par défaut
    Le BULK COLLECT permet que chaque FETCH du curseur alimente n lignes dans le tableau (ici n = 3), d'où un gain de temps lors de l'exécution du curseur. D'ailleurs, tu pourrais aisément augmenter la valeur de LIMIT (500, 1000, 5000, ... à tester pour trouver la valeur optimale).
    En aucun cas, le BULK COLLECT ne peut soulager le buffer du DBMS_OUTPUT.

    Tu trouveras ici des infos et tests de performance sur BULK COLLECT et FORALL :
    http://sheikyerbouti.developpez.com/pl_sql/?page=Chap5
    Des chercheurs qui cherchent, on en trouve, mais des chercheurs qui trouvent, on en cherche !

  6. #6
    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
    Citation Envoyé par vincent_17 Voir le message
    ...
    Le problème est que je ne peux pas passer par un fichier, l'architecture actuelle ne le permet pas, comment je peux faire par une autre méthode ?

    Je n'ai pas très bien saisi ce concept ?
    Qu'est-ce que cela va changer par une autre méthode ?
    Peut être insérer dans une table de log à la place d'afficher avec DBMS_OUTPUT.
    Peut être utiliser DBMS_PIPE pour transmettre l'information vers un daemon qui va se charger de consummer le PIPE et d'afficher les informations par printf.
    Peut être écrire un programme extern en C, ou pour quoi pas en Java, qui fait le printf et l'appeler dans ton code Pl/SQL
    Peut être ... mais toute cela dépendent de tes besoins.

  7. #7
    Expert éminent
    Homme Profil pro
    Big Data / Freelance EURL
    Inscrit en
    Mars 2003
    Messages
    2 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Big Data / Freelance EURL

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 124
    Points : 7 291
    Points
    7 291
    Par défaut
    Je n'ai pas suivi de près ton souci mais il me semble comprendre que tu as un problème de limitation de DBMS_OUTPUT.

    Utilise la fonction DEBUG de Sheik Yerbouti de developpez.com. Je l'ai essayé, en l'adaptant pour mes propres besoins et ça fonctionne très bien

  8. #8
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    Merci pour toutes vos réponses.

    Je vais tenter la méthode DEBUG.

  9. #9
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    Bonjour,

    voici le code que j'ai écrit mais j'ai encore un problème de buffer...
    je pense que je ne me sers pas bien de la méthode DEBUG,
    pouvez-vous m'aider ?

    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
    58
    59
    60
    61
    set serveroutput on 1000000;
     
    CREATE OR REPLACE procedure DEBUG ( PC$Message in VARCHAR2 )
    Is
    PRAGMA AUTONOMOUS_TRANSACTION ;
      LC$Chaine Varchar2(4000) ;
      LN$Tranches PLS_INTEGER ;
      LN$Reste  PLS_INTEGER ;
      LN$Pos PLS_INTEGER := 1 ;
      LN$Inc PLS_INTEGER ;
    Begin
        -- Sortie sur ecran (DBMS_OUTPUT) --
        LN$Inc := 255 ;
        LN$Tranches := Length( PC$Message ) / LN$Inc ;
        LN$Reste    := MOD( Length( PC$Message ), LN$Inc ) ;
        If LN$Reste > 0 Then LN$Tranches := LN$Tranches + 1 ; End if ;
     
        -- Sortie --
        For i in 1..LN$Tranches Loop
           LC$Chaine := Substr( PC$Message, LN$Pos, LN$Inc ) ;
           DBMS_OUTPUT.PUT_LINE( LC$Chaine ) ;
           LN$Pos := LN$Pos + LN$Inc ;
        End loop ;
    End;
    /
     
    declare
     
         Cursor cur is SELECT distinct DOSSIER_GED.NO_DOS_GED from DOSSIER_GED
    , CHANGEMENT_ETAT_DOS_GED
         where DOSSIER_GED.NO_DOS_GED = CHANGEMENT_ETAT_DOS_GED.NO_DOS_GED;
     
         TYPE TYP_TAB_NODOSGED IS TABLE OF DOSSIER_GED.NO_DOS_GED%Type;
     
         Temp_no_dos_ged TYP_TAB_NODOSGED;
     
         Pass pls_integer := 1;
     
    begin
     
          OPEN cur;
     
          LOOP
     
                FETCH  cur BULK COLLECT into Temp_no_dos_ged LIMIT 10000;
     
                FOR i In Temp_no_dos_ged.first..Temp_no_dos_ged.last LOOP
     
                       DEBUG(Temp_no_dos_ged(i));
     
                END LOOP;
     
                Exit when cur%NOTFOUND;
     
          END LOOP;
     
          CLOSE cur;
     
          rollback;
    end;
    /

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    en 10g tu peux essayer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SET serveroutput ON SIZE UNLIMITED
    Sinon, bah faut afficher moins de caractères

  11. #11
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SET serveroutput ON SIZE UNLIMITED
    n'a pas résolu le problème...

    ah je suis embêté avec ça, je pensais que la méthode DEBUG pouvais découper les résultats en les affichant...

    Je ne m'en sers peut être pas bien ?

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    Tu affiches trop de caractères point... y'a rien n'a faire si ce n'est d'écrire dans un fichier (UTL_FILE) plutôt qu'à l'écran (DBMS_OUTPUT).

  13. #13
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    D'accord, peut être que ce n'est pas possible.

    C'est juste que le post de phili_b avec la méthode DEBUG m'avait donné un espoir...

    Dans mon cas, je ne peut pas passer par un fichier car l'architecture en place est très rigide malheureusement...

  14. #14
    Membre confirmé
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Points : 562
    Points
    562
    Par défaut
    Citation Envoyé par vincent_17 Voir le message
    D'accord, peut être que ce n'est pas possible.

    C'est juste que le post de phili_b avec la méthode DEBUG m'avait donné un espoir...

    Dans mon cas, je ne peut pas passer par un fichier car l'architecture en place est très rigide malheureusement...
    Vous pouvez dans ce cas , en lieu et et place du dbms_output faire une insertion dans une table "d'édition" (temporaire Why not) et reprendre le contenu de cette table par un simple "select" via sql*Plus

    PS : Avec l'espoir que la création d'une table soit moins "rigide"
    Signé : Capitaine Jean-Luc Picard

  15. #15
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    malheureusement le création d'une table est aussi rigide que de passer par un fichier...

  16. #16
    Expert éminent
    Homme Profil pro
    Big Data / Freelance EURL
    Inscrit en
    Mars 2003
    Messages
    2 124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Big Data / Freelance EURL

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 124
    Points : 7 291
    Points
    7 291
    Par défaut
    Crées une table de test avec ta procédure dans l'environnement ci-dessous et je verrais si je peux faire quelque chose pour toi:

    developpez.net: [APEX] Oracle en ligne pour vous pour vos requêtes Oracle

  17. #17
    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
    Citation Envoyé par vincent_17 Voir le message
    malheureusement le création d'une table est aussi rigide que de passer par un fichier...
    Faite un traitement par lot alors! Modifiez votre procédure pour qu'elle traite 1000 enregistrements par exemple en commençant avec l'enregistrement numéro X. Il vous faut un order by bien sûr.
    Et ensuite vous le lancez pour les enregistrements 1 - 1000, 1001 - 2000, etc.

  18. #18
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    j'ai retiré le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set serveroutput on 1000000
    au début du code et mis le dbms_output.enable(1000000); entre les balises begin/end, et augmenter la taille du buffer sous TOAD sous l'onglet DBMS_OUTPUT et ça a fonctionné !!

    Merci pour toutes vos réponses !

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    oui, évidemment il aurait fallu commencer par nous préciser l'outil

  20. #20
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    116
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 116
    Points : 66
    Points
    66
    Par défaut
    Effectivement j'aurais dû préciser l'outil.

    Par ailleurs, pour info, si vous lancez le script pl/sql depuis un script .ksh (un script shell) il faut ajouter en en-tête :

    mettre le : dbms_output.enable(1000000) entre les balises begin/end et là ça loggeras sans problèmes logiquement.

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

Discussions similaires

  1. [MySql] équivalent du DBMS_OUTPUT.PUT_LINE ?
    Par taskax dans le forum MySQL
    Réponses: 2
    Dernier message: 27/07/2010, 07h56
  2. problème avec dbms_output.put_line
    Par kurah dans le forum PL/SQL
    Réponses: 8
    Dernier message: 15/10/2009, 20h31
  3. problème avec dbms_output.put_line
    Par bensabdel dans le forum PL/SQL
    Réponses: 2
    Dernier message: 19/05/2009, 15h34
  4. Dbms_output.put_line() : où consulter ?
    Par babylone7 dans le forum PL/SQL
    Réponses: 1
    Dernier message: 12/11/2008, 22h01
  5. Stockage de dbms_output.put_line dans fichier spool
    Par pascal_T dans le forum PL/SQL
    Réponses: 2
    Dernier message: 23/10/2008, 09h08

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