转:http://blog.csdn.net/m_changgong/article/details/4540632
错误发生的原因是在执行存储过程操作中,读取游标少读取了某个或者某些列。
不过,这似乎是不可能发生的,因为编译阶段都会报错。
下面演示错误的发生以及解决方法。
1.创建测试表USERS。
CREATE TABLE "USERS2" (
"USERNAME" VARCHAR2(20 BYTE),
"USERPASS" VARCHAR2(20 BYTE),
"COUNTER" NUMBER(11,0)
) ;
2.创建测试过程PROC_DEMO,故意少读取一列。
create or replace
PROCEDURE PROC_DEMO AS
uname varchar2(20);
upass varchar2(20);
counter number;
BEGIN
DECLARE CURSOR CUR_USERS is
select * from USERS;
BEGIN
OPEN CUR_USERS;
LOOP
FETCH CUR_USERS INTO uname,upass;
EXIT when CUR_USERS%NOTFOUND;
dbms_output.put_line('uname:'||uname);
dbms_output.put_line('upass:'||upass);
dbms_output.put_line('counter:'||counter);
END LOOP;
CLOSE CUR_USERS;
END;
END PROC_DEMO;
编译以上过程,发生错误:
Error(12,5): PL/SQL: SQL Statement ignored
Error(12,5): PLS-00394: 在 FETCH 语句的 INTO 列表中值数量出现错误
连编译都通不过,更不要说在执行时出现如下错误:ORA-00932: 数据类型不一致: 应为 -, 但却获得 –。
以上是在SQL Developer进行的测试。在PROC_DEMO声明游标CUR_USERS并读取,如果少读取了某个或者某些列编译通不过。如果游标CUR_USERS不是在过程中显示声明的而是通过调用返回游标类型数据的过程中获取的,那么少读取了某个或者某些列编译可能能够通过。
3.创建返回游标和基本类型数据的过程。
该过程封装在包中,包声明如下:
create or replace PACKAGE PACKAGE_TEST AS
TYPE CURSOR_TYPE IS REF CURSOR;
PROCEDURE PROC_TEST(
COUNTER OUT NUMBER,
CUR_USERS OUT CURSOR_TYPE
);
END PACKAGE_TEST;
创建包体如下:
create or replace PACKAGE BODY PACKAGE_TEST
IS
PROCEDURE PROC_TEST(
COUNTER OUT NUMBER,
CUR_USERS OUT CURSOR_TYPE
)
IS
SELECT_SQL VARCHAR2(200);
BEGIN
SELECT_SQL := 'SELECT COUNT(*) FROM USERS';
EXECUTE IMMEDIATE SELECT_SQL INTO COUNTER;
SELECT_SQL := 'SELECT USERNAME,USERPASS FROM USERS';
OPEN CUR_USERS FOR SELECT_SQL;
END PROC_TEST;
END PACKAGE_TEST;
4.创建测试过程PROC_CLIENT。
create or replace
PROCEDURE PROC_CLIENT AS
TYPE CURSOR_TYPE IS REF CURSOR;
CUR_USERS CURSOR_TYPE;
COUNTER number;
uname varchar2(20);
upass varchar2(20);
BEGIN
--调用PACKAGE_TEST中的过程PROC_TEST
PACKAGE_TEST.PROC_TEST(COUNTER,CUR_USERS);
--打印结果信息
DBMS_OUTPUT.PUT_LINE('COUNTER:'||COUNTER);
DBMS_OUTPUT.PUT_LINE('返回的游标中的数据:');
LOOP
FETCH CUR_USERS INTO uname;
EXIT when CUR_USERS%NOTFOUND;
dbms_output.put_line('uname:'||uname);
--dbms_output.put_line('upass:'||upass);
END LOOP;
CLOSE CUR_USERS;
END PROC_CLIENT;
运行PROC_CLIENT,发生如下错误:
ORA-00932: 数据类型不一致: 应为 -, 但却获得 -
ORA-06512: 在 "DEMO.PROC_CLIENT", line 14
ORA-06512: 在 line 2
原因是PACKAGE_TEST.PROC_TEST返回的游标CUR_USERS是表USERS两个列
USERNAME和USERPASS的结果集,但是在PROC_CLIENT中读取该游标时只读取了USERNAME。
解决方法:
将读取游标的语句修改为如下所示:
FETCH CUR_USERS INTO uname,userpass;
EXIT when CUR_USERS%NOTFOUND;
dbms_output.put_line('uname:'||uname);
dbms_output.put_line('upass:'||upass);
总结,通过上面的演示可以发现其实这是个很表面的错误,仅仅因为游标是从别的过程中声明并产生数据集的,所以躲过了很多编译错误,直到运行时才发生莫名其妙的错误。
相关推荐
ora-01033:oracle initialization or shutdown in progress 解决方法 ora-01033:oracle initialization or shutdown in progress 解决方法 ora-01033:oracle initialization or shutdown in progress 解决方法 ora-...
在运行查询SELECT * FROM V$SESSION 会出现ORA-29275:部分多字节字符的错误,这是什么原因开始我不得其解,网上也没有介绍什么好办法。本文给出答案。
ORA-32001:write to spfile requested but no spfile is in use请求写入spfile,但没有使用spfile的解决方法 在输入以下语句中报了这样的错误: SQL>alter system set control_files=’/u01/app/oracle/oradata/prod/...
ORA-12154: TNS: 无法解析指定的连接标识符的解决方法
ORA-00031:标记要终止的会话解决方案; ORA-00031:标记要终止的会话解决方案;
ORA-01036:非法的变量名/编号 oracle特有的错误
调整参数后引起,ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 3 2768M 的解决方案
oracle12c程序连接时异常: ORA-01017: 用户名/口令无效; 登录被拒绝 的解决方案。
oracle 12 c ORA-01017: 用户名/口令无效; 登录被拒绝
-- 解决ORA-00904: "WMSYS"."WM_CONCAT": 标识符无效 的文件包....... -- 解决ORA-00904: "WMSYS"."WM_CONCAT": 标识符无效 的文件包....... -- 解决ORA-00904: "WMSYS"."WM_CONCAT": 标识符无效 的文件包....... ...
NULL 博文链接:https://3w1h.iteye.com/blog/1211779
oracle报错ora-12541:TNS无监听程序
错误描述:oracle远程连接服务器出现 ORA-12170 TNS:连接超时 错误检查:有很多是oracle自身安装的问题,但是我这里服务器配置正常,监听正常,服务正常,远程可以ping通服务器。 这里主要是防火墙问题,解决办法: ...
CLOB字段类型报错 ORA-01704:文字字符串过长的解决
解决ORACLE TNS: 无法解析指定的连接标识符; 里面有步骤
ora-12514:TNS:监听程序当前无法识别连接描述符中请求的服务bug,解决文档.
ORA-12541 TNSno listener 的解决方案 ORA-12541 TNSno listener 的解决方案
“ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值”
oracle19c缺少的函数
ORA-12518 TNS:监听程序无法分发客户机连接,在您安装好数据库后配置连接数据库的过程中遇到这类问题应该很头疼吧,不过,当您还是四处查资料来解决您遇到的另你头疼的问题时,如果不经意间看到了这则贴子,那请您升...