如何获取Oracle中CLOB
列的大小(以字节为单位)?
LENGTH()
和DBMS_LOB.getLength()
都返回CLOB
中使用的字符数,但我需要知道使用了多少字节(我正在处理多字节字符集)。
答案 0 :(得分:17)
经过一番思考后我想出了这个解决方案:
LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000)))
SUBSTR
仅返回前4000个字符(最大字符串大小)
TO_CHAR
从CLOB
转换为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(DBMS_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0)
+NVL(LENGTHB(TO_CHAR(DBMS_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