如何在Oracle中获取CLOB列的大小(以字节为单位)?

时间:2009-11-25 14:17:53

标签: sql oracle clob

如何获取Oracle中CLOB列的大小(以字节为单位)?

LENGTH()DBMS_LOB.getLength()都返回CLOB中使用的字符数,但我需要知道使用了多少字节(我正在处理多字节字符集)。

7 个答案:

答案 0 :(得分:17)

经过一番思考后我想出了这个解决方案:

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

SUBSTR仅返回前4000个字符(最大字符串大小)

TO_CHARCLOB转换为VARCHAR2

LENGTHB返回字符串使用的字节长度。

答案 1 :(得分:16)

我正在添加我的评论作为答案,因为它解决了原始问题的范围更广,而不是接受的答案。注意:您仍必须知道数据的最大长度和多字节字符的大致比例。

如果CLOB大于4000字节,则需要使用DBMS_LOB.SUBSTR而不是SUBSTR。 请注意,金额偏移参数在DBMS_LOB.SUBSTR中相反。

接下来,您可能需要将少于4000的数量子串,因为此参数是字符的数量,如果您有多字节字符,那么4000个字符将超过4000 bytes long,您将获得ORA-06502: PL/SQL: numeric or value error: character string buffer too small,因为子字符串结果需要适合具有4000字节限制的VARCHAR2。确切地说,您可以检索多少个字符取决于数据中每个字符的平均字节数。

所以我的答案是:

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,并根据数据的每个字符的平均字节数调整块大小。

答案 2 :(得分:6)

尝试使用CLOB大小大于VARCHAR2的那个:

我们必须将CLOB拆分为“VARCHAR2兼容”大小的部分内容,通过CLOB数据的每个部分运行lengthb,并汇总所有结果。

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

答案 3 :(得分:5)

NVL(长度(clob_col_name),0)适合我。

答案 4 :(得分:4)

简单的解决方案是将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)。 但我认为使用Unicode(UTF-8)Oracle实例,此解决方案必须正确: - )

我希望渲染感谢Nashev发布了一个将clob转换为blob How convert CLOB to BLOB in Oracle?的解决方案以及用德语编写的这篇文章(代码在PL / SQL中)13ter.info.blog,它还提供了一个函数将blob转换为clob!

有人可以用Unicode(UTF-8)CLOB测试2个命令,所以我确定这适用于Unicode吗?

答案 5 :(得分:3)

使用表名从dba_lobs检查LOB段名称。

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 :(得分:-1)

它只能工作到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