今天有个学生问我调用包里面具有游标类型的输出参数,可是在用PL/SQL程序调用的时候居然报出参数个数或类型错误的异常信息,于是自己也试了一下,果然是出错了。然后就自己琢磨了一下、查查资料和问问同事,原来问题是很简单的,先看一下程序的结构代码:
CREATE OR REPLACE PACKAGE Pkg_Student
IS
TYPE StudentType IS REF CURSOR RETURN TB_STUDENT%ROWTYPE;
PROCEDURE Pro_student
(
pi_ClassId IN TB_STUDENT.CLASSID%TYPE,
Po_student OUT StudentType
);
END Pkg_Student;
--实现包体代码
CREATE OR REPLACE PACKAGE BODY Pkg_Student
IS
PROCEDURE Pro_student
(
pi_ClassId IN TB_STUDENT.CLASSID%TYPE,
Po_student OUT StudentType
)
AS
BEGIN
IF pi_ClassId=1 THEN
OPEN Po_student FOR SELECT * FROM TB_STUDENT WHERE TB_STUDENT.CLASSID=1;
ELSIF pi_ClassId=2 THEN
OPEN Po_student FOR SELECT *FROM TB_STUDENT WHERE TB_STUDENT.CLASSID=2;
ELSE
OPEN Po_student FOR SELECT *FROM TB_STUDENT WHERE TB_STUDENT.CLASSID=3;
END IF;
END;
END Pkg_Student;
--执行调用包里面的存储过程
DECLARE
TYPE StudentType IS REF CURSOR RETURN TB_STUDENT%ROWTYPE;
v_student StudentType;
v_ClassID TB_STUDENT.CLASSID%TYPE:=1;
BEGIN
Pkg_Student.Pro_student(v_ClassID,v_student);
END;
像上面那样执行就会出现参数个数或类型错误;于是,纠正了一下代码如下:
DECLARE
v_student Pkg_Student.StudentType;
v_ClassID TB_STUDENT.CLASSID%TYPE:=1;
BEGIN
Pkg_Student.Pro_student(v_ClassID,v_student);
END;
原因如下:
1、StudentType本身是在包里面声明和应用,其作用域也在包内部而已;
2、若外部程序要调用包里面具有游标类型参数的过程或函数时,那么必须在外部显示调用包
里面的游标声明,而不是在外面重新定义一个游标声明和游标变量。而且注意的是游标变量本身也是动态的,是一个引用类型,不依赖于工作区。
好了,对于这个问题的分析就到这边了.........希望对别人有帮助。(帮助他人就是帮助自己)