ORA-06502:PLSQL:数值或值错误:字符串缓冲区太小
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORA-06502:PLSQL:数值或值错误:字符串缓冲区太小相关的知识,希望对你有一定的参考价值。
CREATE OR REPLACE FUNCTION "FN_GETBIGTEXT" ( Tabflag in VARCHAR2)
return varchar2
as
type rc is ref cursor;
str varchar2(4000);
sep varchar2(2);
val varchar2(4000);
cur rc;
begin
open cur for
'SELECT tbi_memo FROM hi_tab_bigtext
WHERE tbi_flag='''||Tabflag||'''';
loop
fetch cur into val;
Exit When Cur%Notfound;
str := str || val;
end loop;
Close Cur;
--Dbms_Output.Put_Line(str);
return str;
end fn_getbigtext;
这是我的函数,执行这个函数时报下面的错误,怎么修改啊?网上查了好多都不行
目测,这个不用自定义函数吧,oracle中有现成的
select wm_concat(tbi_memo) FROM hi_tab_bigtext WHERE tbi_flag= 参数这种转完是逗号分隔的,你再用replace把逗号去掉就可以啊
执行立即错误:PL/SQL:数字或值错误:字符到数字转换错误
【中文标题】执行立即错误:PL/SQL:数字或值错误:字符到数字转换错误【英文标题】:Execute Immediate Error: PL/SQL: numeric or value error: character to number conversion error 【发布时间】:2018-07-11 06:24:44 【问题描述】:我有以下代码,我试图动态传递 IF 语句条件:
DECLARE
v_flag NUMBER(2);
v_if_statement VARCHAR2(500);
v_sql_statement VARCHAR2(500);
v_criteria VARCHAR2(150);
v_condition VARCHAR2(30) := '%sales% > 300';
BEGIN
v_criteria := REPLACE(v_condition , '%sales%' , 500.32);
v_if_statement := 'IF :'||v_criteria||' '||
'THEN :v_flag := 1;'||' '||
'ELSE :v_flag := 0;'||' '||
'END IF;';
v_sql_statement := 'BEGIN '||v_if_statement||' END;';
EXECUTE IMMEDIATE v_sql_statement USING IN v_criteria, OUT v_flag;
dbms_output.put_line('The output is : '||v_flag);
END;
我收到以下错误: ORA-06502: PL/SQL: 数字或值错误: 字符到数字的转换错误
任何帮助将不胜感激!
谢谢..
【问题讨论】:
在构建变量v_sql_statement之后,在执行它之前,把它打印出来看看全貌——然后你就可以很容易地发现问题了。 【参考方案1】:如果您按照@Ychdziu 的建议打印出最终生成的语句,您会看到它最终为:
BEGIN IF :500.32 > 300 THEN :v_flag := 1; ELSE :v_flag := 0; END IF; END;
这不是你想要的。您要么需要提供要检查的值 (500.32) 作为绑定变量,如@Ychdziu 的回答中所示,要么将条件连接到语句中而不尝试创建另一个绑定变量:
DECLARE
v_flag NUMBER(2);
v_if_statement VARCHAR2(500);
v_sql_statement VARCHAR2(500);
v_criteria VARCHAR2(150);
v_condition VARCHAR2(30) := '%sales% > 300';
BEGIN
v_criteria := REPLACE(v_condition , '%sales%' , 500.32);
v_if_statement := 'IF '||v_criteria||' '||
'THEN :v_flag := 1;'||' '||
'ELSE :v_flag := 0;'||' '||
'END IF;';
v_sql_statement := 'BEGIN '||v_if_statement||' END;';
dbms_output.put_line('statament: '||v_sql_statement);
EXECUTE IMMEDIATE v_sql_statement USING OUT v_flag;
dbms_output.put_line('The output is : '||v_flag);
END;
/
现在生成的语句是
BEGIN IF 500.32 > 300 THEN :v_flag := 1; ELSE :v_flag := 0; END IF; END;
所以只有一个绑定变量。
但如果可以的话,通常最好绑定变量。在您的示例代码中,整个条件似乎是一个变量(我假设这只是一个练习,但它可以传入或来自表),因此您可以将两者结合起来并用绑定变量替换 %sales%
占位符改为参考:
DECLARE
v_flag NUMBER(2);
v_if_statement VARCHAR2(500);
v_sql_statement VARCHAR2(500);
v_criteria VARCHAR2(150);
v_condition VARCHAR2(30) := '%sales% > 300';
BEGIN
v_criteria := REPLACE(v_condition , '%sales%' , ':v_value');
v_if_statement := 'IF '||v_criteria||' '||
'THEN :v_flag := 1;'||' '||
'ELSE :v_flag := 0;'||' '||
'END IF;';
v_sql_statement := 'BEGIN '||v_if_statement||' END;';
dbms_output.put_line('statament: '||v_sql_statement);
EXECUTE IMMEDIATE v_sql_statement USING IN 500.32, OUT v_flag;
dbms_output.put_line('The output is : '||v_flag);
END;
/
不是生成的语句是:
BEGIN IF :v_value > 300 THEN :v_flag := 1; ELSE :v_flag := 0; END IF; END;
您可以通过USING
子句直接传递您想要检查的实际值500.32 - 可以像我在这里所做的那样作为文字,或者使用单独的数字变量。
【讨论】:
【参考方案2】:这个查询有几个问题: 1)SQL语句本身结构不好; 2) DB 尝试将 v_criteria 转换为数字类型,但 v_criteria 是 '500.32 > 300' - 你不能这样转换。 试试这个方法:
DECLARE
v_flag NUMBER(2);
v_if_statement VARCHAR2(500);
v_sql_statement VARCHAR2(500);
v_criteria VARCHAR2(150);
BEGIN
v_criteria := 300.32;
v_if_statement := q'[IF :v_criteria > 300
THEN :v_flag := 1;
ELSE :v_flag := 0;
END IF;]';
v_sql_statement := 'BEGIN '||v_if_statement||' END;';
dbms_output.put_line('v_sql_statement is : '||v_sql_statement);
EXECUTE IMMEDIATE v_sql_statement USING IN v_criteria, OUT v_flag;
dbms_output.put_line('The output is : '||v_flag);
END;
【讨论】:
以上是关于ORA-06502:PLSQL:数值或值错误:字符串缓冲区太小的主要内容,如果未能解决你的问题,请参考以下文章
执行立即错误:PL/SQL:数字或值错误:字符到数字转换错误
ORA-06502: 非常基本的字符串函数出现数字或值错误,这是啥原因?
ORA-06502 PL/SQL:数字或值错误:字符到数字的转换错误;
ORA-06502: PL/SQL: 数字或值错误: 字符到数字的转换错误