Sql 从CLOB到VARCHAR2选择尽可能多的数据,数据中包含多字节字符

Sql 从CLOB到VARCHAR2选择尽可能多的数据,数据中包含多字节字符,sql,oracle,substr,clob,multibyte,Sql,Oracle,Substr,Clob,Multibyte,多字节字符给我带来了很多痛苦 对这个问题有什么建议吗 我有一个CLOB字段,可能包含一些多字节字符,我需要在SQL中进行选择,并将此字段转换为下游进程的字符串,目前我正在使用: SELECT DBMS_LOB.SUBSTR( description, 4000, 1 ) FROM table 但是上面命令中的4000是字符长度,而不是字节长度。因此,我不得不改为3000来处理任何可能潜入数据中的多字节字符,否则将出现缓冲区大小错误 问题在于,对于不包含多字节字符的记录,它可能会不必要地截断比需

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

对这个问题有什么建议吗

我有一个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选择…

可能会使用SUBSTR截断生成的varchar2:

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

杰弗里的思维过程是正确的,但阿尔坎也是正确的。刚刚遇到了同样的问题,这是我的解决方案。您必须能够创建一个函数,但:

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

        );

这不应该是“…和SUBSTRB”吗?(SUBSTRB而不是SUBSTR)出于兴趣:您知道如果前3999个字符是一个字节长,而第4000个字符是多字节长,会发生什么情况吗?它是否会在位置4000处返回错误的字符(因为它将多字节字符的第一个字节解释为单字节字符)?不,如果“描述”包含多字节字符,它将不起作用,最里面的DBMS_LOB.SUBSTR在到达SUBSTRB之前已经遇到了一个字符串缓冲区错误。如果我们有一个DBMS_LOB.SUBSTRB,那么我的问题就解决了!回答弗兰克的问题,是的,角色会被某种形式的截断。尝试从DUAL中选择SUBSTRB('ÄÊÍÓØA B C D E',1,1);这从对偶中选择SUBSTRB('196ÊÍÓØA B C D E',1,2);我在中基于这个答案创建了一个全面的(我希望如此!)示例,我已经测试并确认使用这个函数比Jeffrey的解决方案效果更好。然而,我不明白为什么。这不是在做同样的事情吗,而是在函数中而不是在内联中?为什么在这里会有所不同呢?我怀疑区别在于PL/SQL中的varchar2可以增加到32767字节,而在SQL中(至少在11g和更早版本中),最大值是4000字节。