Comment obtenir la taille en octets d'une colonne de CLOB Oracle?
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).
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(DBMS_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0)
+NVL(LENGTHB(TO_CHAR(DBMS_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