DBMS_LOB.SUBSTR 限制处理大于 1 字节的字符吗

Posted

技术标签:

【中文标题】DBMS_LOB.SUBSTR 限制处理大于 1 字节的字符吗【英文标题】:Is DBMS_LOB.SUBSTR limitation in dealing with characters which are > 1 byte 【发布时间】:2015-07-19 14:55:01 【问题描述】:
create table t ( x int, y clob );

create or replace procedure p( p_x in int, p_new_text in varchar2 )
    as
    begin
            insert into t values ( p_x, p_new_text );
    end;
    /

exec p(1, rpad('*',4002,'*') );

exec p(2, rpad('é',4002,'é') );

select x, dbms_lob.getlength(y) from t;

select x, dbms_lob.substr(y,4000,1) from t where x = 1; -- this one does not give error and function correctly finds 4000 characters as each character 1 byte

select x, dbms_lob.substr(y,4000,1) from t where x = 2; -- function not able to find 4000 characters and gives error as é is more than 1 byte.
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 1

问题是当 clob 字段中可能有一些字符占用超过 1 个字节时,从 oracle 中使用什么来查找 4000 个字符。

【问题讨论】:

【参考方案1】:

问题不在于substr 函数。它是 SQL 中 varchar2 的最大长度:4000 bytes

这意味着即使这个语句也会失败:

select x, dbms_lob.substr(y,2001,1) from t where x = 2

这是真的,因为 2001 两个字节的字符是 4002 字节,这超出了数据类型可以处理的范围。对于这些情况,您应该使用clob

【讨论】:

问题是 dbms_lob.substr 是否真的可以确定 clob 列中的 4000 个字符要添加到上面的示例中,即使此查询失败,因为 substr 函数无法识别超过 4000 限制的位置。从 t 中选择 x, dbms_lob.substr(y,1500,1) 其中 x = 2;如果不使用 substr 怎么处理? 是的,它计算字符数。你不是说他们有4000个吗? ;) 检查 1 个字符,你会看到。将其表示为 varchar 而不是子字符串本身时会出错。

以上是关于DBMS_LOB.SUBSTR 限制处理大于 1 字节的字符吗的主要内容,如果未能解决你的问题,请参考以下文章

ora-64203 怎么解决

2个sql 函数dbms_lob.substr 和 wm_concat

如何在 sql*plus 中使用 dbms_lob.substr

数据库-Oracle如何将clob数据以字符串打印出来

Plsql查询clob类型字段数据

如何选择整个clob列oracle?