SQL:如何从 sql 中的函数输出中获取子字符串?

Posted

技术标签:

【中文标题】SQL:如何从 sql 中的函数输出中获取子字符串?【英文标题】:SQL: How to get substring from function output in sql? 【发布时间】:2013-10-03 13:10:50 【问题描述】:

在我的应用程序之一中。我们有一个查询,实际上我们正在调用一个函数并且函数将 o/p 作为字符串返回。有人知道如何从返回的函数中获取子字符串吗?

我是这样用的

select substr(myfunction(),0,4000) from dual.

我遇到了以下问题。

ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太 小。

请帮帮我。提前致谢。

【问题讨论】:

我相信 Oracle 使用从 1 开始的字符串索引,那么您是否尝试过使用 substr(myfunction(),1,4000) 代替? 我怀疑错误是从您的函数中抛出的 - 如果您发布代码会很有用.. @Dan 在这种情况下使用 0 作为索引也可以,例如: SELECT SUBSTR('1234567890', 0, 5) FROM dual; -- 打印 12345 【参考方案1】:

由于您正在应用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 "***.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 

【讨论】:

【参考方案2】:

很可能您尝试存储的字符数超出了您在函数中使用的某个变量所允许的字符数。见:PL/SQL: numeric or value error: character string buffer too small %ROWTYPE

最简单的例子:

DECLARE
  v_varchar2_test VARCHAR2(5);
BEGIN
  v_varchar2_test := '123456';
END;

错误是,就像你的情况一样,ORA-06502。

【讨论】:

【参考方案3】:

确保函数返回的值类型正确; 我刚刚尝试过这样的:

create or replace 
FUNCTION MONTH
(DATA IN DATE)
RETURN VARCHAR IS
BEGIN
  RETURN TO_CHAR(DATA, 'MM');
END;

和电话:

SELECT substr(MONTH(SYSDATE),0,1) FROM DUAL;

它成功了。

【讨论】:

以上是关于SQL:如何从 sql 中的函数输出中获取子字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL 子查询中获取字符串数组

Oracle sql:仅获取子字符串的特定部分

如何从 SQL 中的用户定义函数返回多个值

sql中如何提取从数据库中所获得时间的年份

如何从 SQL 中的 DateTime 格式获取时间?

如何获取存储过程以输出从 SQL*Plus 中的 select 语句返回的表?