ORA-06502: 非常基本的字符串函数出现数字或值错误,这是啥原因?

Posted

技术标签:

【中文标题】ORA-06502: 非常基本的字符串函数出现数字或值错误,这是啥原因?【英文标题】:ORA-06502: Numeric or Value Error on very basic string function, what gives?ORA-06502: 非常基本的字符串函数出现数字或值错误,这是什么原因? 【发布时间】:2013-02-27 17:36:43 【问题描述】:

这是代码...这不是完整的代码。我把它修剪到第一个错误发生的地方:

 FUNCTION get (  
    p_sql_o                         OUT VARCHAR2
  ) RETURN VARCHAR2 AS
  str_sql           VARCHAR2(4000);
  BEGIN
    str_sql := ' SELECT * FROM ( SELECT A.*, ROWNUM RNUM FROM ( ' ||
               ' SELECT item_code, ' ||
               ' item_desc, ' ||
               ' monitor, ' ||
               ' measured, ' ||
               ' inventory, ' ||
               ' (measured - inventory) adj_amount, ' ||
               ' (inventory_cost * measured) measured_cost, ' ||
               'inventory';
    RETURN str_sql;
  EXCEPTION
    WHEN OTHERS THEN
    RETURN NULL;
  END get;

显然,SQL 不完整,但我没有运行它。我只是返回 SQL 字符串,但我仍然得到一个错误:

ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小 ORA-06512: 在第 6 行

这令人费解。有没有人知道为什么会这样?

【问题讨论】:

您是否在get 函数中遇到错误?或者您是否在调用 get 函数的行的调用者中收到错误?如果是后者,那就意味着调用者没有为函数分配足够大的字符串来返回数据。此外,很奇怪,函数中有一个OUT 参数,从名称来看,除了RETURN 语句之外,它似乎还用于向调用者返回一条SQL 语句。这里的OUT参数完全是多余的。 p_sql_o 的值是多少? 我可以毫无错误地运行它......所以是的,有点奇怪。您远未达到 4k 限制,因此即使您在 UTF-16 DB 中运行它,字节数也不会达到 4k。我怀疑您正在尝试将输出放入一个太小的变量中。你怎么称呼它? 如果我消除字符串中的最后一个“库存”行,则没有错误。在我到达 RETURN 之前发生错误。 【参考方案1】:

既然您已经说过您不会尝试动态执行您正在创建的 SQL,那么其中内容的语法和正确性,或者它可能返回的内容的长度,显然是无关紧要的。你没有对你的 p_sql_o OUT 参数做任何事情,所以这也不会导致这个问题。这只让str_sql 成为罪魁祸首,正如贾斯汀昨天暗示的那样,它在函数中被声明为足够大,并且函数本身编译正常 - 所以看起来它必须是它的调用方式才是问题所在。

你提到如果你删除'inventory'它会起作用,这会将字符串的长度从201个字符减少到192个字符,所以我猜你已经在调用者中将此设置为200个字符,例如:

declare
    str_sql varchar2(200);
    p_sql_o varchar2(4000);
begin
    str_sql := get(p_sql_o);
end;
/

declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 5

请注意,这里报告的行号是5,而不是您之前的@​​987654326@; caller 中有错误的那一行,而不是函数内部发生赋值的那一行。如果我在调用者声明中将其设为 str_sql varchar2(250);,那么它就可以工作(但它也可能是 4000 以匹配函数中的声明)。

declare
    str_sql varchar2(250);
    p_sql_o varchar2(4000);
begin
    str_sql := get(p_sql_o);
end;
/

PL/SQL procedure successfully completed.

但是p_sql_o 仍然是空的,因为你从未设置它。看起来OUT 参数是多余的。也许您打算将 SQL 字符串放入其中,并且已在调用者中声明为足够大;但随后不清楚返回值是什么 - 您可能只想完全删除 OUT 参数,并确保您将返回值放入的调用者中的变量足够大。

【讨论】:

调试器实际上设置了返回 200 个字符。奇怪的是,当我试图从 .NET 应用程序中调用 SQL 字符串时……它做了同样的事情。我不确定罪魁祸首是什么,但调试器实际上将结果变量设置为只有 200 个字符。增加这有助于缓解这个问题。【参考方案2】:

您是否尝试过仅针对 SP 之外的数据库运行 SQL 脚本?这将有助于确定 sql 语法是否正确以及您是否返回了预期的内容。看起来您希望得到 4000 字节或更小的响应。你确定那是被退回的东西吗?我没有看到 Where 子句。也许您返回的多行超出了您的限制?诚然,我对存储过程不太熟悉,所以我可能会离开。

【讨论】:

【参考方案3】:

在这里,您使用 p_sql_o 作为输出参数,而不是在函数内分配任何值。 所以 p_sql_o 将保留它之前在调用此函数行之后的代码中的值。

正如您定义的 str_sql 只能容纳 4000 个字符,如果您的连接字符串超出该限制,它将给出 字符串缓冲区太小 ORA-06512 错误。

当您连接字符串以创建选择语句时,请检查您是否正确使用了单引号,或者您根本没有使用它们。如果发生这种情况,那么在执行动态选择语句时,您可能会收到此错误 ORA-06502: PL/SQL: numeric or value error:

【讨论】:

以上是关于ORA-06502: 非常基本的字符串函数出现数字或值错误,这是啥原因?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle ORA-06502 PL/SQL:数字或值错误:字符到数字的转换错误

ORA-06502: PL/SQL: 在空游标的情况下出现数字或值错误

ORA-06502: PL/SQL: 数字或值错误,我贴出来,大家帮我改一下,以前没怎么写过存储过程。。

ORA-06502: PL/SQL: 数字或值错误: 字符到数字的转换错误

错误 ORA-06502:PL/SQL:数字或值错误:字符到数字的转换错误 ORA-06512:在第 22 行

PL/SQL: 数字或值错误 - ORA-06502