7

多字节字符给我带来了很大的痛苦。

对这个问题有什么建议吗?

我有一个可能包含一些多字节字符的 CLOB 字段,我需要在 SQL 中选择并将该字段转换为下游进程的字符串,目前我正在使用:

SELECT DBMS_LOB.SUBSTR( description, 4000, 1 ) FROM table

但是上面命令中的 4000 是字符长度,而不是字节。所以我不得不更改为 3000 来处理任何可能潜入数据中的多字节字符,否则会发生缓冲区大小错误。

问题在于不包含多字节字符的记录,它可能会不必要地截断比它需要的更多的数据。(4000 是字符串限制,我们可以/必须忍受它。)

有没有办法做一些相当于:

SELECT DBMS_LOB.SUBSTR( description, 4000bytes, 1 ) FROM table

这样我就可以得到尽可能多的数据。

注意:我不能创建临时表/视图,不能使用 PL/SQL,只能使用 SQL SELECT...

4

2 回答 2

8

Jeffrey 的思维过程还可以,但是 alchn 也是对的。刚刚遇到同样的问题,这是我的解决方案。不过,您必须能够创建一个函数:

Create Or Replace Function clob_substr(p_clob   In Clob
                                      ,p_offset In Pls_Integer
                                      ,p_length In Pls_Integer) Return Varchar2 Is
Begin
  Return substrb(dbms_lob.substr(p_clob
                                ,p_length
                                ,p_offset)
                ,1
                ,p_length);
End;
/

这是它的使用演示:

Select c
      ,clob_substr(c
                  ,1
                  ,4000)
  From (

        Select xmlelement("t", rpad('é', 4000, 'é'), rpad('é', 4000, 'é')).extract('//text()').getclobval() c
          From dual

        );
于 2012-10-08T08:50:20.903 回答
5

也许用 SUBSTR 截断生成的 varchar2:

SELECT SUBSTRB( DBMS_LOB.SUBSTR( description, 4000, 1 ), 1, 4000) FROM table
于 2012-08-23T06:06:52.583 回答