如何CLOB
在 Oracle 中获取列的大小(以字节为单位)?
LENGTH()
并且DBMS_LOB.getLength()
都返回中使用的字符数,CLOB
但我需要知道使用了多少字节(我正在处理多字节字符集)。
经过一番思考,我想出了这个解决方案:
LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000)))
SUBSTR
仅返回前 4000 个字符(最大字符串大小)
TO_CHAR
转换CLOB
为VARCHAR2
LENGTHB
返回字符串使用的字节长度。
我将我的评论添加为答案,因为它解决了比接受的答案更广泛的案例的原始问题。注意:您仍然必须知道数据的最大长度和多字节字符的大致比例。
如果您的 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
因为子串结果需要适合具有 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,并根据数据的每个字符的平均字节数调整块大小。
对于大于 VARCHAR2 的 CLOB 大小,试试这个:
我们必须将 CLOB 拆分为“VARCHAR2 兼容”大小的部分,遍历 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;
/
NVL(length(clob_col_name),0) 对我有用。
简单的解决方案是将 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
我在没有使用 Unicode(UTF-8) 的情况下在 Oracle 10g 上对此进行了测试。但我认为这个解决方案必须是正确的使用 Unicode(UTF-8) Oracle 实例:-)
我想要渲染感谢 Nashev 发布了一个将 clob 转换为 blob 的解决方案如何在 Oracle 中将 CLOB 转换为 BLOB?对于这篇用德语写的帖子(代码在 PL/SQL 中)13ter.info.blog还提供了一个将 blob 转换为 clob 的函数!
有人可以测试 Unicode(UTF-8) CLOB 中的 2 个命令,所以我确定这适用于 Unicode 吗?
使用表名从 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;
它只能工作到 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