如何将BLOB转换为CLOB?

10

我正在使用Oracle 11g,想要获取文本的长度。通常我会使用select length(myvar) from table,但是这次无法这样做。

我想查询的表有一个BLOB列,保存了字符或照片。我想知道我的BLOB列中有多少个字符。

我尝试使用UTL_RAW.CAST_TO_VARCHAR2(myblob) from tableBLOB转换为字符,但这个函数似乎不能正确地工作,或者我可能犯了一个错误。

例如: 我的BLOB中有单词Section,当我在数据库中以十六进制形式查看它时,我看到S.e.c.t.i.o.n.。我不知道为什么每个字母之间都有点。 然后我使用了这个查询:

select UTL_RAW.CAST_TO_VARCHAR2(myblob) 
from table

这个查询的结果是'S',所以它并不是我BLOB中完整的单词,当我进行这个查询时:

select length(UTL_RAW.CAST_TO_VARCHAR2(myblob))
from table

结果是18,但单词Sections并不含18个字符。

我试图将BLOB转换为VARCHAR,虽然我认为最好的选择应该是CLOB,因为它可以保存的文本长度超过了VARCHAR的限制。我尝试通过执行以下查询来实现这一点(我不确定这是否正确,但这是我在互联网上找到的):

select UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(myblob, 32767, 1))
from table

此查询还会返回 'S'


DBMS_LOB.GET_LENGTH() 可能会有所帮助。 - cagcowboy
2
欢迎来到变长字符编码的奇妙世界。 - Mike Park
@cagcowboy 我尝试使用 select DBMS_LOB.GET_LENGTH(myblob) from table,但是出现了错误 ORA-00904 invalid identifier。 - user1739469
4个回答

22

对于任何想知道如何将 blob 转换为 clob 的人,这里是一个例子。

create function clobfromblob(p_blob blob) return clob is
      l_clob         clob;
      l_dest_offsset integer := 1;
      l_src_offsset  integer := 1;
      l_lang_context integer := dbms_lob.default_lang_ctx;
      l_warning      integer;

   begin

      if p_blob is null then
         return null;
      end if;

      dbms_lob.createTemporary(lob_loc => l_clob
                              ,cache   => false);

      dbms_lob.converttoclob(dest_lob     => l_clob
                            ,src_blob     => p_blob
                            ,amount       => dbms_lob.lobmaxsize
                            ,dest_offset  => l_dest_offsset
                            ,src_offset   => l_src_offsset
                            ,blob_csid    => dbms_lob.default_csid
                            ,lang_context => l_lang_context
                            ,warning      => l_warning);

      return l_clob;

   end;

1
两件事情: 1.你需要创建一个临时CLOB 2.如果p_blob为null,最好提前退出。begin if p_blob is null then return null; end if; DBMS_LOB.CREATETEMPORARY(l_clob, false); dbms_lob.converttoclob(... - Chris R. Donnelly
归功于这个示例代码的人:https://oracle-base.com/dba/miscellaneous/blob_to_clob.sql - Jared Still

5

要将BLOB转换为CLOB,请尝试以下方法:

SELECT TO_CLOB(UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(MYBLOB,2000))) 
FROM MYTABLE;

4
SELECT DBMS_LOB.GetLength( myblob ) length_in_bytes
  FROM table

将返回BLOB长度(以字节为单位)。你的BLOB中的字符数据可能使用UTF-16字符集进行编码,因此字节数可能是字符数的两倍(取决于正在使用的Unicode版本和存储的特定数据,某些字符可能需要4个字节的存储空间,但您处理任何这些字符的可能性相对较小)。

您可以使用DBMS_LOB.ConvertToClob过程将BLOB转换为CLOB(尽管由于这是一个过程,您需要在PL / SQL块中调用它)。作为转换的一部分,您几乎肯定需要指定数据编码的字符集,我的假设是您的应用程序使用UTF-16字符集,但这只是一种假设。


抱歉点了踩,是不小心的,编辑之前无法点赞。 - Brian McGinity

2

仅转换为CLOB:

最初的回答

select TO_CLOB(UTL_RAW.CAST_TO_VARCHAR2(YOURCLOB)) from DUAL;

受到Craig的启发,没有大小限制。
原始答案:Original Answer

执行上述模式后发现以下错误;ORA-22835: CLOB转换为CHAR或BLOB转换为RAW时缓冲区太小(实际值:3904,最大值:2000) 22835. 00000-“ CLOB转换为CHAR或BLOB转换为RAW时缓冲区太小(实际值:%s,最大值:%s)” *原因:尝试将CLOB转换为CHAR或BLOB转换为RAW,其中LOB大小大于CHAR和RAW类型的缓冲区限制。 - Raja
1
将 BLOB 强制转换为 varchar2,如果没有先检查大小,那么这不是一个好主意。在 PL/SQL 中,varchar2 的限制为单字节字符的 32767。在数据库中,单字节字符的限制为 4000。 - Jared Still

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接