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 :

Taille de buffer dépassé pour DBMS_LOB


Sujet :

PL/SQL Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 52
    Points : 35
    Points
    35
    Par défaut Taille de buffer dépassé pour DBMS_LOB
    Bonjour,

    J'ai ecrit la procedure 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
    20
    21
    22
    CREATE OR REPLACE PROCEDURE CREATE_INDEX(rid IN ROWID, tlob IN OUT NOCOPY CLOB)
    IS
    BEGIN
    DBMS_LOB.CREATETEMPORARY(tlob, TRUE);
    FOR c1 IN (SELECT ID_DOCUMENT FROM DOCUMENT WHERE rowid = rid)
    LOOP
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<DOCUMENT>'), '<DOCUMENT>');
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<DOCUMENT_TITLE>'), '<DOCUMENT_TITLE>');
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH(NVL(c1.TITLE, ' ')), NVL(c1.TITLE, ' '));
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</DOCUMENT_TITLE>'), '</DOCUMENT_TITLE>');
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</DOCUMENT>'), '</DOCUMENT>');
    FOR c2 IN (SELECT TITRE,TEXTE FROM PAGE WHERE ID_DOCUMENT = c1.ID_DOCUMENT)
    LOOP
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<PAGE>'), '<PAGE>');
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<PAGE_TEXT>'), '<PAGE_TEXT>');
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH(NVL(c2.TEXTE, ' ')), NVL(c2.TEXTE, ' '));
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</PAGE_TEXT>'), '</PAGE_TEXT>');
    DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</PAGE>'), '</PAGE>');
    END LOOP;
    END LOOP;
    END;
    /
    Selon le document que je traite, la taille du texte de la page peut dépasser la taille du buffer de dbms_lob de 32767 bytes. J'ai des cas ou le texte faire 53975 bytes par exemples.
    Dans ce cas la procedure plante et je ne sais pas du tout comment contourner ce probleme... Peux on augmenter la taille du buffer ?

    Merci !

  2. #2
    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
    Je suppose que TEXTE est un CLOB ? lisez-le par tranches avec DBMS_LOB.READ().
    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

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 52
    Points : 35
    Points
    35
    Par défaut
    Oui texte est un CLOB.

    En fait je suis cette doc oracle:
    http://download.oracle.com/docs/cd/B...c.htm#i1006810

    Cette procédure me permet de concaténer le titre et le texte de ces deux tables pour ensuite créer un index avec tous les documents de ma base.
    Cette procédure doit donc retourner mon titre et mon texte concaténé.

    Si j'utilise read pour lire peu a peu je risque d'être confronté au mémé problème non ?

    Merci.

  4. #4
    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
    Non, car vous faite un WriteAppend() de chaque chunk lu par le Read().
    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

  5. #5
    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
    Quelque chose comme cela (non testé)
    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
     
    Declare
      buffer RAW(32767);
      amt BINARY_INTEGER := 32767;
      pos INTEGER := 1;
      clob   CLOB;
    Begin
      FOR c2 IN (SELECT TITRE,TEXTE FROM PAGE WHERE ID_DOCUMENT = c1.ID_DOCUMENT)
      LOOP
       BEGIN
         LOOP
           dbms_lob.read (c2.TEXTE, amt, pos, buffer); 
           pos := pos + amt;
           -- traitement du tampon
           dbms_lob.writeappend (clob, amt, buffer);
         END LOOP;
       EXCEPTION
         WHEN NO_DATA_FOUND THEN
           -- fin des données du LOB --
           null
       End;
      End loop; 
    End;
    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

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 52
    Points : 35
    Points
    35
    Par défaut
    Merci beaucoup de votre aide !

    J'ai testé cette procédure et ca fonctionne deja mieux.
    A priori ca boucle trois fois sur le texte mais j'ai l'erreur suivante sur le writeappend:
    ORA-06502: PL/SQL : erreur numérique ou erreur sur une valeur

    J'ai beau chercher je ne vois pas ce qui cloche, voici ce que j'ai écrit:

    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
     
        DECLARE
          buffer VARCHAR2(32767);
          amt BINARY_INTEGER := 32767;
          pos INTEGER := 1;
        BEGIN
          FOR c2 IN (SELECT TITRE,TEXTE FROM PAGE WHERE ID_DOCUMENT = c1.ID_DOCUMENT)
          LOOP
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<PAGE>'), '<PAGE>'); 
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<PAGE_TITRE>'), '<PAGE_TITRE>'); 
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH(NVL(c2.TITRE, ' ')), NVL(c2.TITRE, ' '));
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</PAGE_TITRE>'), '</PAGE_TITRE>'); 
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH('<PAGE_TEXTE>'), '<PAGE_TEXTE>'); 
            BEGIN
              LOOP
                DBMS_LOB.READ(c2.TEXTE, amt, pos, buffer); 
                DBMS_LOB.WRITEAPPEND(tlob, amt, buffer);
                pos := pos + amt;
              END LOOP;
              EXCEPTION
                WHEN NO_DATA_FOUND THEN
                  NULL;
            END;
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</PAGE_TEXTE>'), '</PAGE_TEXTE>'); 
            DBMS_LOB.WRITEAPPEND(tlob, LENGTH('</PAGE>'), '</PAGE>');
          END LOOP;

  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
    Et si vous déplacez le
    pos := pos + amt; juste après le READ() ?
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 52
    Points : 35
    Points
    35
    Par défaut
    Cela ne change rien :/
    Je ne comprend pas pourquoi il me renvoit cette erreur... J'ai beau chercher sur le net je ne trouve rien de similaire...

  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
    Généralement, ça correspond à un dépassement de capacité, avec une variable sous-dimensionnée ou d'un mauvais type.
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 52
    Points : 35
    Points
    35
    Par défaut
    A mon avis il s'agit d'un erreur au niveau de la quantité à ecrire et non du contenu du buffer en lui meme.

    Ce qui est etrange c'est que si j'affiche la taille de amt ou du buffer cela semble correct:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
              LOOP
                DBMS_LOB.READ(c5.TEXTE, amt, pos, buffer); 
                pos := pos + amt;
                DBMS_OUTPUT.PUT_LINE('amt = ' || amt);
                DBMS_OUTPUT.PUT_LINE('buf size = ' || length(buffer));
                DBMS_LOB.WRITEAPPEND(tlob, amt, buffer);
              END LOOP;
    M'affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    amt = 32767
    buf size = 32767
    amt = 21208
    buf size = 21208
    32767 + 21208 = 53975 bytes du texte total... Donc cela semble correct.
    Peut etre une erreur de type ou un byte en trop qu'on ne verrait pas ?

    Merci en tout cas de votre aide precieuse !

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 52
    Points : 35
    Points
    35
    Par défaut
    En fait je crois que l'erreur est au niveau de mon code appelant, je l'ai modifié et la procedure a l'air de passer maintenant !
    Merci beaucoup pour votre aide en tout cas, ca m'a bien aidé !

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

Discussions similaires

  1. Ajuster la taille du buffer pour recv
    Par figarojuju dans le forum Réseau
    Réponses: 11
    Dernier message: 04/09/2010, 12h55
  2. Réponses: 39
    Dernier message: 27/03/2007, 20h25
  3. [CSS] Modifier la taille de mon image pour mon bouton
    Par bouchette63 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 11/08/2006, 10h15
  4. [Stratégie] taille de tableau max pour alleger les ressources systemes
    Par ceres02 dans le forum Collection et Stream
    Réponses: 9
    Dernier message: 24/02/2006, 19h06
  5. [CSS] Taille de police relative (pour de vrai!!)
    Par djynwk dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 02/08/2005, 14h44

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