由于您正在应用substr,因此您的函数返回的值可能大于 4000 个字符。如果是这种情况,那么你会从 SQL 中得到这个错误,你无法避免它。它试图将长字符串值分配给(隐式)SQL 级别 varchar2,当然也不能超过 4000 个字符,然后再将其传递给 substr 函数。
您必须将substr 添加到函数的返回值中,或者如果有时从可以处理长值的某个地方调用它,您可以有一个仅返回前 4000 个字符的包装函数 - 所以您可以根据需要取合适的值。
用一个虚拟函数来演示(低效!)创建一个大字符串:
create or replace function myfunction(strlen number) return varchar2 is
str varchar2(32767) := 'X';
begin
while length(str) < least(strlen, 32767) loop
str := str || 'X';
end loop;
return str;
end myfunction;
/
这很好,因为函数的输出没有超过 SQL varchar2 的大小:
select length(substr(myfunction(4000),0,4000)) from dual;
LENGTH(SUBSTR(MYFUNCTION(4000),0,4000))
---------------------------------------
4000
但这会导致您的错误,因为函数的输出太长:
select length(substr(myfunction(4001),0,4000)) from dual;
SQL Error: ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "STACKOVERFLOW.MYFUNCTION", line 7
06502. 00000 - "PL/SQL: numeric or value error%s"
使用简单的包装函数作为解决方法:
create or replace function trunc_myfunction(strlen number) return varchar2 is
begin
return substr(myfunction(strlen), 0, 4000);
end;
/
select length(substr(trunc_myfunction(4000),0,4000)) from dual;
LENGTH(SUBSTR(TRUNC_MYFUNCTION(4000),0,4000))
---------------------------------------------
4000
select length(substr(trunc_myfunction(4001),0,4000)) from dual;
LENGTH(SUBSTR(TRUNC_MYFUNCTION(4001),0,4000))
---------------------------------------------
4000
select length(substr(trunc_myfunction(32767),0,4000)) from dual;
LENGTH(SUBSTR(TRUNC_MYFUNCTION(32767),0,4000))
----------------------------------------------
4000