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

rag*_*rag 33 sql oracle clob

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

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

rag*_*rag 18

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

 LENGTHB(TO_CHAR(SUBSTR(<CLOB-Column>,1,4000)))
Run Code Online (Sandbox Code Playgroud)

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

TO_CHAR转换CLOBVARCHAR2

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

  • 但这只适用于你的CLOB很小的情况. (24认同)

And*_*cer 16

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

如果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(DBM??S_LOB.SUBSTR(<CLOB-Column>,3000,3001))),0)
+NVL(LENGTHB(TO_CHAR(DBM??S_LOB.SUBSTR(<CLOB-Column>,6000,6001))),0)
+...
Run Code Online (Sandbox Code Playgroud)

您可以根据需要添加尽可能多的块来覆盖最长的CLOB,并根据数据的每个字符的平均字节数调整块大小.


小智 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;
/
Run Code Online (Sandbox Code Playgroud)


小智 5

NVL(length(clob_col_name),0)为我工作。

  • 不,`length` 返回以 *characters* 为单位的长度,而不是字节。 (2认同)

sch*_*ebe 5

简单的解决方案是将 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;
Run Code Online (Sandbox Code Playgroud)

用于获取字节数的 SQL 命令是

SELECT length(clob2blob(fieldname)) as nr_bytes 
Run Code Online (Sandbox Code Playgroud)

或者

SELECT dbms_lob.getlength(clob2blob(fieldname)) as nr_bytes
Run Code Online (Sandbox Code Playgroud)

我已经在没有使用 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 吗?