Question

Comment puis-je obtenir la taille en octets d'une colonne de CLOB dans Oracle?

LENGTH() et DBMS_LOB.getLength() à la fois le numéro de retour de caractères utilisés dans le CLOB mais je dois savoir combien d'octets sont utilisés (je traite charactersets multi-octets).

Était-ce utile?

La solution

Après quelques réflexions que je suis venu avec cette solution:

 LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000)))

retourne SUBSTR seulement les 4000 premiers caractères (taille de la chaîne max)

TO_CHAR convertit CLOB à VARCHAR2

LENGTHB renvoie la longueur en octets utilisés par la chaîne.

Autres conseils

J'ajoute mon commentaire comme une réponse, car il résout le problème d'origine pour une série de cas plus large que la réponse acceptée. . Remarque: vous devez quand même connaître la longueur maximale et la proportion approximative de caractères multi-octets que vos données auront

Si vous avez une CLOB supérieure à 4000 octets, vous devez utiliser DBMS_LOB.SUBSTR plutôt que SUBSTR. Notez que les montant et décalage paramètres sont inversés dans DBMS_LOB.SUBSTR.

Ensuite, vous devrez peut-substring un montant inférieur à 4000, parce que ce paramètre est le nombre de caractères , et si vous avez des caractères multi-octets puis 4000 caractères sera plus de 4000 octets longue, et vous obtiendrez ORA-06502: PL/SQL: numeric or value error: character string buffer too small parce que le résultat doit substring tenir dans un VARCHAR2 qui a une limite de 4000 octets. Exactement le nombre de caractères que vous pouvez récupérer dépend du nombre moyen d'octets par caractère dans vos données.

Donc, ma réponse est:

LENGTHB(TO_CHAR(DBMS_LOB.SUBSTR(<CLOB-Column>,3000,1)))
+NVL(LENGTHB(TO_CHAR(DBM‌​S_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0)
+NVL(LENGTHB(TO_CHAR(DBM‌​S_LOB.SUBSTR(<CLOB-Column>,6000,6001))),0)
+...

vous permet d'ajouter autant de morceaux que vous avez besoin pour couvrir votre plus long CLOB, et ajuster la taille du morceau selon octets par-caractères moyenne de vos données.

Essayez celui-ci pour CLOB tailles plus grandes que VARCHAR2:

Nous devons diviser le CLOB dans certaines parties de tailles « VARCHAR2 compatibles », exécutez lengthb par chaque partie des données CLOB, et de résumer tous les résultats.

declare
   my_sum int;
begin
   for x in ( select COLUMN, ceil(DBMS_LOB.getlength(COLUMN) / 2000) steps from TABLE ) 
   loop
       my_sum := 0;
       for y in 1 .. x.steps
       loop
          my_sum := my_sum + lengthb(dbms_lob.substr( x.COLUMN, 2000, (y-1)*2000+1 ));
          -- some additional output
          dbms_output.put_line('step:' || y );
          dbms_output.put_line('char length:' || DBMS_LOB.getlength(dbms_lob.substr( x.COLUMN, 2000 , (y-1)*2000+1 )));
          dbms_output.put_line('byte length:' || lengthb(dbms_lob.substr( x.COLUMN, 2000, (y-1)*2000+1 )));
          continue;
        end loop;
        dbms_output.put_line('char summary:' || DBMS_LOB.getlength(x.COLUMN));
        dbms_output.put_line('byte summary:' || my_sum);
        continue;
    end loop;
end;
/

NVL (longueur (clob_col_name), 0) fonctionne pour moi.

La solution simple est de jeter CLOB à blob, puis demander longueur de blob!

Le problème est que Oracle ne dispose pas d'une fonction qui jettent CLOB à blob, mais nous pouvons simplement définir une fonction pour faire

create or replace
FUNCTION clob2blob (p_in clob) RETURN blob IS 
    v_blob        blob;
    v_desc_offset PLS_INTEGER := 1;
    v_src_offset  PLS_INTEGER := 1;
    v_lang        PLS_INTEGER := 0;
    v_warning     PLS_INTEGER := 0;  
BEGIN
    dbms_lob.createtemporary(v_blob,TRUE);
    dbms_lob.converttoblob
        ( v_blob
        , p_in
        , dbms_lob.getlength(p_in)
        , v_desc_offset
        , v_src_offset
        , dbms_lob.default_csid
        , v_lang
        , v_warning
        );
    RETURN v_blob;
END;

La commande SQL à utiliser pour obtenir le nombre d'octets est

SELECT length(clob2blob(fieldname)) as nr_bytes 

ou

SELECT dbms_lob.getlength(clob2blob(fieldname)) as nr_bytes

Je l'ai testé sur Oracle 10g sans utiliser Unicode (UTF-8). Mais je pense que cette solution doit être correcte en utilisant Unicode (UTF-8) instance Oracle: -)

Je veux rendre grâce à Nashev qui a mis en ligne une solution pour convertir clob de blob Comment convertir CLOB blob dans Oracle? et ce message écrit en allemand (le code est en PL / SQL) 13ter.info.blog qui donnent en outre une fonction de conversion CLOB!

Quelqu'un peut-il tester les 2 commandes en Unicode (UTF-8) CLOB donc je suis sûr que cela fonctionne avec Unicode?

Vérifiez le nom du segment LOB de dba_lobs en utilisant le nom de la table.

select TABLE_NAME,OWNER,COLUMN_NAME,SEGMENT_NAME from dba_lobs where TABLE_NAME='<<TABLE NAME>>';

Utilisez le nom du segment pour trouver les octets utilisés dans DBA_SEGMENTS.

select s.segment_name, s.partition_name, bytes/1048576 "Size (MB)"
from dba_segments s, dba_lobs l
where s.segment_name = l.segment_name
and s.owner = '<< OWNER >> ' order by s.segment_name, s.partition_name;

Il ne fonctionne que jusqu'à 4000 octets, si le clob est plus grand que 4000 octets nous utilisons ces

declare
v_clob_size clob;

begin

      v_clob_size:= (DBMS_LOB.getlength(v_clob)) / 1024 / 1024;
      DBMS_OUTPUT.put_line('CLOB Size   ' || v_clob_size);   
end;

ou

select (DBMS_LOB.getlength(your_column_name))/1024/1024 from your_table
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top