Подтвердить что ты не робот

Как получить размер в байтах столбца CLOB в Oracle?

Как получить размер в байтах столбца CLOB в Oracle?

LENGTH() и DBMS_LOB.getLength() оба возвращают количество символов, используемых в CLOB, но мне нужно знать, сколько байтов используется (я имею дело с многобайтовыми наборами символов).

4b9b3361

Ответ 1

После некоторого размышления я придумал это решение:

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

SUBSTR возвращает только первые 4000 символов (максимальный размер строки)

TO_CHAR преобразует от CLOB в VARCHAR2

LENGTHB возвращает длину в байтах, используемых строкой.

Ответ 2

Я добавляю свой комментарий в качестве ответа, потому что он решает исходную проблему для более широкого круга дел, чем принятый ответ. Примечание: вы все равно должны знать максимальную длину и приблизительную долю многобайтовых символов, которые будут иметь ваши данные.

Если у вас CLOB больше 4000 байт, вам нужно использовать DBMS_LOB.SUBSTR, а не SUBSTR. Обратите внимание, что параметры количества и смещения изменяются в DBMS_LOB.SUBSTR.

Далее вам может понадобиться подстроить сумму меньше 4000, потому что этот параметр - количество символов, и если у вас многобайтовые символы, то 4000 символов будут иметь длину более 4000 байт, и вы получите ORA-06502: PL/SQL: numeric or value error: character string buffer too small, потому что результат подстроки должен соответствовать VARCHAR2, который имеет ограничение в 4000 байт. Точно, сколько символов вы можете получить, зависит от среднего количества байт на символ в ваших данных.

Итак, мой ответ:

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)
+...

где вы добавляете столько кусков, сколько вам нужно, чтобы покрыть свой самый длинный CLOB, и отрегулируйте размер куска в соответствии со средними байтами за символ ваших данных.

Ответ 3

Попробуйте сделать это для CLOB-размеров больше, чем VARCHAR2:

Мы должны разделить CLOB в части "совместимых с VARCHAR2" размеров, запустить lengthb через каждую часть данных CLOB и суммировать все результаты.

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;
/

Ответ 4

NVL (length (clob_col_name), 0) работает для меня.

Ответ 5

Проверьте имя сегмента LOB из dba_lobs, используя имя таблицы.

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

Теперь используйте имя сегмента, чтобы найти байты, используемые в 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;

Ответ 6

Простое решение - привести CLOB к BLOB, а затем запросить длину BLOB!

Проблема в том, что в Oracle нет функции, которая преобразует CLOB в BLOB, но мы можем просто определить функцию для этого

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;

Команда SQL, используемая для получения количества байтов:

SELECT length(clob2blob(fieldname)) as nr_bytes 

или же

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

Я проверил это на Oracle 10g без использования Unicode (UTF-8). Но я думаю, что это решение должно быть правильным с использованием экземпляра Oracle Unicode (UTF-8) :-)

Я хочу сделать рендеринг благодаря Нашеву, который опубликовал решение по конвертированию clob в blob. Как конвертировать CLOB в BLOB в Oracle? и к этому посту, написанному на немецком языке (код на PL/SQL) 13ter.info.blog, который дополнительно дает функцию для преобразования BLOB-объектов в Clob!

Может кто-нибудь протестировать 2 команды в Unicode (UTF-8) CLOB, так что я уверен, что это работает с Unicode?

Ответ 7

Он работает только до 4000 байт. Что, если clob больше 4000 байт, мы используем этот

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;

или

select (DBMS_LOB.getlength(your_column_name))/1024/1024 from your_table