oralce pl/sql 拼接表字段的字符串出错 求解

--测试功能:拼接出表Stest的字段名d1,d2,再计算数值,进行把值插入新表stemp的字段名d1,d2中
set serveroutput on
create or replace procedure pr_needcarCount(pr_GroupNameClass number,pr_GroupName varchar2)
v_di number:=1;
v_dname varchar2(10);
v_value number:=0;
begin
if pr_GroupNameClass=1 then
while v_di<=2 loop
v_dname:='d'||v_di;
select round(v_dname/2,2) as v_value from Stest where d0=pr_GroupName;
dbms_output.put_line('计算得到的数字为'||v_value);
--insert into stemp (d||v_di) values v_value where d0=pr_GroupName;
v_di:=v_di+1;
end loop;
end if;
end;

Warning: Procedure created with compilation errors

SQL> show error;
Errors for PROCEDURE NBTESTDATA.PR_NEEDCARCOUNT:

LINE/COL ERROR
-------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2/9 PLS-00103: 发现了符号 "V_DI" 当您等待下列事项之一发生时: ; is with authid as cluster order using external deterministic parallel_enable pipelined 符号 "is" 取代了 "V_DI" 才可以继续作业.
第二次修改后执行情况为:
SQL> CREATE OR REPLACE PROCEDURE Pr_Needcarcount IS
2 v_Di NUMBER := 1;
3 v_Dname VARCHAR2(10);
4 v_Value NUMBER := 0;
5 v_i number:=1;
6 BEGIN
7 --IF v_i = 1 THEN
8 WHILE v_Di <= 2 LOOP
9 v_Dname := 'd' || v_Di;
10 SELECT v_Dname into v_Value FROM Stest WHERE D0 = 'a';
11 v_Value:=round(v_Value/2,2);
12 Dbms_Output.Put_Line('计算得到的数字为' || v_Value);
13 --insert into stemp (d||v_di) values v_value where d0=pr_GroupName;
14 v_Di := v_Di + 1;
15 END LOOP;
16 --END IF;
17 END;
18 /

Procedure created

SQL> exec Pr_Needcarcount;

begin Pr_Needcarcount; end;

ORA-06502: PL/SQL: 数字或值错误: 字元到数字转换错误
ORA-06512: 在 "NBTESTDATA.PR_NEEDCARCOUNT", line 10
ORA-06512: 在 line 2

to:流浪云风

你们俩说的根本不是一回事,看了半天才看明白楼主要问什么了,他的意思是
v_Dname中所存储的是列名 D1或者是D2,然后用select into语句把数据库列
D1,D2的值Into到变量v_Value中,D1、D2列在数据库中应该是数值型的,
楼主显然把列和变量搞混了,想认为select v_dname into v_value from,,,
这条语句中,oracle会中将v_dname替换成D1、D2列进行查询的。
to: jh10fox
你的代码需要用到动态sql的。
CREATE OR REPLACE PROCEDURE Pr_Needcarcount(Pr_Groupnameclass NUMBER,
Pr_Groupname VARCHAR2) IS
v_Di NUMBER := 1;
v_Dname VARCHAR2(10);
v_Value NUMBER := 0;
v_Sql varchar2(1000);
BEGIN
IF Pr_Groupnameclass = 1 THEN
WHILE v_Di <= 2 LOOP
v_Dname := 'd' || v_Di;
-- 这里是新增的,需要用动态sql执行的
v_sql:= 'select ' || v_dname || ' from Stest WHERE D0 =' || Chr(39) || Pr_Groupname || Chr(39);
execute immediate v_sql returning into v_value;
v_Value:=round(v_Value/2,2);
Dbms_Output.Put_Line('计算得到的数字为' || v_Value);
-- 这里是新增的,插入语句同样也是需要用动态sql执行的
--v_sql:= 'insert into stemp (' || v_Dname || ') values || '(' || to_char(v_value) ||')';
--execute immediate v_sql;
v_Di := v_Di + 1;
END LOOP;
END IF;
END;追问

to: sxdtgsh
你理解的就是我想要的功能。动态SQL过去没有接触过,看起来功能很强大。
按你修改的语句,编译成功,调用时问题如下:
SQL> exec Pr_Needcarcount(1,'a');
begin Pr_Needcarcount(1,'a'); end;
ORA-06547: RETURNING 子句必须与 INSERT, UPDATE, 或 DELETE 叙述句一起使用
ORA-06512: 在 "NBTESTDATA.PR_NEEDCARCOUNT", line 15
ORA-06512: 在 line 2

追答

语法写错了。多了个returning
execute immediate v_sql into v_value;

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-11-14
创建过程是缺失关键字is,在参数列表右括号后增加 is 即可,具体代码如下:
CREATE OR REPLACE PROCEDURE Pr_Needcarcount(Pr_Groupnameclass NUMBER,
Pr_Groupname VARCHAR2) IS
v_Di NUMBER := 1;
v_Dname VARCHAR2(10);
v_Value NUMBER := 0;
BEGIN
IF Pr_Groupnameclass = 1 THEN
WHILE v_Di <= 2 LOOP
v_Dname := 'd' || v_Di;
SELECT Round(v_Dname / 2, 2) AS v_Value FROM Stest WHERE D0 = Pr_Groupname;
Dbms_Output.Put_Line('计算得到的数字为' || v_Value);
--insert into stemp (d||v_di) values v_value where d0=pr_GroupName;
v_Di := v_Di + 1;
END LOOP;
END IF;
END;

问题解决后,记得采纳。追问

问题解决后,一定会采纳的。

我增加了is,修改简化了语句,见上面的问题补充(此处有字数限制,放不下)。编译成功了,但调用时却出错,是什麽原因?

追答

v_Dname := 'd' || v_Di;
SELECT Round(v_Dname / 2, 2) INTO v_Value FROM Stest WHERE D0 = 'a';
这里有问题,v_dname 是字符串,里面含有‘d’这个字符,但后使用Round(v_Dname / 2, 2) 肯定会报错啊,用字符串除以2,这样是不合理的。我想你这里是不是写错了啊。应该是从Stest 表中查出一列number类型的值,然后除以2,再round

追问

我修改为,还是有问题,想不明白问题所在:
v_Dname := 'd' || v_Di;
SELECT v_Dname into v_Value FROM Stest WHERE D0 = 'a';
v_Value:=round(v_Value/2,2);

调用时报:
ORA-06502: PL/SQL: 数字或值错误: 字元到数字转换错误
ORA-06512: 在 "NBTESTDATA.PR_NEEDCARCOUNT", line 10
ORA-06512: 在 line 2

追答

不是round的问题。而是v_Value/2的问题,v_Value除以2,而v_Value是字符串,如果这个字符串是纯数字是可以自动转换的,可问题出在,v_Value的值包含【d】这个字母。d除以2当然会报错了。只有数字才能使用乘除法。字母除以2是没法算的啊。
所以v_Value里面必须只是数字才行。

追问

我定义的是:
v_Dname VARCHAR2(10); --字符
v_Value NUMBER := 0; --数字

我的用法是:从表Stest 查出D0 = 'a'时,字段D1的数字值给v_Value ,再对v_Value 进行运算。不清楚下面的语句会出错?
SELECT v_Dname into v_Value FROM Stest WHERE D0 = 'a';

追答

SELECT v_Dname into v_Value FROM Stest WHERE D0 = 'a';
这个查询没有问题,你不从表里取字段也没有问题。
问题是v_Dname 变量中含有字母,它不是纯数字,所以除以2会报错。不论你怎么处理,只要v_Dname 里存的是纯数字就没有问题了。
这么说能理解吗?

追问

我语句中除以2的是对v_Value进行的,不是对v_Dname

v_Dname := 'd' || v_Di;
SELECT v_Dname into v_Value FROM Stest WHERE D0 = 'a';
v_Value:=round(v_Value/2,2);

追答

v_Dname := 'd' || v_Di;
SELECT v_Dname into v_Value FROM Stest WHERE D0 = 'a';
v_Value:=round(v_Value/2,2);
这样写的话,在select时就会报错的。不能把字符串into到 v_Value 里的,因为 v_Value 是number类型。而v_Dname := 'd' || v_Di;之后,v_Dname的值含有字母,字符串不能放到number变量中。要是再不理解我就解释不明白了。

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网