Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 17/01/2008, 17h42   #1
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
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 :

Citation:
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;
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 18h19   #2
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
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
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 21h43   #3
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 320
Points : 5 839
Points : 5 839
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2008, 10h11   #4
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
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.
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2008, 11h27   #5
Membre expérimenté
 
Inscription : juillet 2007
Messages : 495
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2007
Messages : 495
Points : 585
Points : 585
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 !
dgi77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2008, 13h20   #6
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 320
Points : 5 839
Points : 5 839
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/01/2008, 14h13   #7
Membre Expert
 
Homme
Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)
Inscription : mars 2003
Messages : 645
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 41
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)

Informations forums :
Inscription : mars 2003
Messages : 645
Points : 1 165
Points : 1 165
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
phili_b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2008, 14h57   #8
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
Merci pour toutes vos réponses.

Je vais tenter la méthode DEBUG.
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 09h50   #9
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
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 :
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;
/
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 09h52   #10
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
en 10g tu peux essayer :

Code :
SET serveroutput ON SIZE UNLIMITED
Sinon, bah faut afficher moins de caractères
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 10h02   #11
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
le code :

Code :
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 ?
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 10h05   #12
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
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).
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 10h19   #13
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
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...
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 13h33   #14
Membre éprouvé
 
Avatar de argoet
 
Inscription : mai 2002
Messages : 535
Détails du profil
Informations forums :
Inscription : mai 2002
Messages : 535
Points : 461
Points : 461
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
argoet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2008, 15h07   #15
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
malheureusement le création d'une table est aussi rigide que de passer par un fichier...
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2008, 20h56   #16
Membre Expert
 
Homme
Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)
Inscription : mars 2003
Messages : 645
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 41
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)

Informations forums :
Inscription : mars 2003
Messages : 645
Points : 1 165
Points : 1 165
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
phili_b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2008, 21h09   #17
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 320
Points : 5 839
Points : 5 839
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2008, 09h40   #18
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
j'ai retiré le
Code :
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 !
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2008, 10h20   #19
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
oui, évidemment il aurait fallu commencer par nous préciser l'outil
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2008, 11h53   #20
Nouveau Membre du Club
 
Inscription : janvier 2008
Messages : 116
Détails du profil
Informations forums :
Inscription : janvier 2008
Messages : 116
Points : 33
Points : 33
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.
vincent_17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 06h55.


 
 
 
 
Partenaires

Hébergement Web