--先定义包及包体,定义SYS_REFCURSOR的游标类型及记录类型
CREATE OR REPLACE PACKAGE PKG_CURSOR IS
--游标,多行,单行,非全列单行
TYPE TYP_REFCURSOR IS REF CURSOR RETURN DEPT%ROWTYPE;
TYPE TYP_REC IS RECORD(V_DEPTNO DEPT.DEPTNO%TYPE,V_DNAME DEPT.DNAME%TYPE);
TYPE TYP_TAB_REC IS TABLE OF TYP_REC;
FUNCTION FUNC_IN_CURSOR(TYP_REFCURSOR_1 TYP_REFCURSOR)
RETURN TYP_TAB_REC PIPELINED;
CREATE OR REPLACE PACKAGE PKG_CURSOR IS
--游标,多行,单行,非全列单行
TYPE TYP_REFCURSOR IS REF CURSOR RETURN DEPT%ROWTYPE;
TYPE TYP_REC IS RECORD(V_DEPTNO DEPT.DEPTNO%TYPE,V_DNAME DEPT.DNAME%TYPE);
TYPE TYP_TAB_REC IS TABLE OF TYP_REC;
FUNCTION FUNC_IN_CURSOR(TYP_REFCURSOR_1 TYP_REFCURSOR)
RETURN TYP_TAB_REC PIPELINED;
END PKG_CURSOR;
-------------------------------------------------------------------------------------------------------------
--定义包体
--定义包体浪费了好多时间
--小结:如果函数的步骤太多,每步标上作什么注解,这样出错便于定位调试,不然一行行看会晕的
--
CREATE OR REPLACE PACKAGE body PKG_CURSOR IS
--1,函数的游标输入参数
--2,
--定义函数
FUNCTION FUNC_IN_CURSOR(TYP_REFCURSOR_1 IN TYP_REFCURSOR) --输入参数是包中定义的游标类型
RETURN TYP_TAB_REC PIPELINED --返回类型必须是集合类型,此集合类型也在包中定义
IS
TYP_REC_1 TYP_REC;--记录类型在包中定义
TYP_REFCURSOR_2 TYP_REFCURSOR_1%rowtype;--此步是关键,此变量的类型是基于输入参数和%ROWTYPE,这样就把输入参数与单行记录联系起来
BEGIN
LOOP
--获取输入变量游标变量到标注是:此步是关键 的变量中
FETCH TYP_REFCURSOR_1 INTO TYP_REFCURSOR_2;--另一个单记录变量
--游标退出的条件,注:是游标变量,即输入参数
EXIT WHEN TYP_REFCURSOR_1%NOTFOUND;--
--用此步是关键把值传递给记录类型的变量中,这样就把输入参数游标与此步是关键所对应的变量及记录变型联系起来了
TYP_REC_1.V_DEPTNO:=TYP_REFCURSOR_2.DEPTNO;
TYP_REC_1.V_DNAME:=TYP_REFCURSOR_2.DNAME;
--管道函数一定要用此句PIPE ROW,后跟要传递的记录变量,即最终显示的变量
PIPE ROW(TYP_REC_1);
END LOOP;
--记:如下的关闭游标与RETURN在LOOP END LOOP之外发生
--用完游标一定要关闭,此和常规的游标操作一样,不然浪费资源
CLOSE TYP_REFCURSOR_1;
--这是管道函数特有的,用于返回控制权给调用方
RETURN;
END;
END PKG_CURSOR;
--定义包体浪费了好多时间
--小结:如果函数的步骤太多,每步标上作什么注解,这样出错便于定位调试,不然一行行看会晕的
--
CREATE OR REPLACE PACKAGE body PKG_CURSOR IS
--1,函数的游标输入参数
--2,
--定义函数
FUNCTION FUNC_IN_CURSOR(TYP_REFCURSOR_1 IN TYP_REFCURSOR) --输入参数是包中定义的游标类型
RETURN TYP_TAB_REC PIPELINED --返回类型必须是集合类型,此集合类型也在包中定义
IS
TYP_REC_1 TYP_REC;--记录类型在包中定义
TYP_REFCURSOR_2 TYP_REFCURSOR_1%rowtype;--此步是关键,此变量的类型是基于输入参数和%ROWTYPE,这样就把输入参数与单行记录联系起来
BEGIN
LOOP
--获取输入变量游标变量到标注是:此步是关键 的变量中
FETCH TYP_REFCURSOR_1 INTO TYP_REFCURSOR_2;--另一个单记录变量
--游标退出的条件,注:是游标变量,即输入参数
EXIT WHEN TYP_REFCURSOR_1%NOTFOUND;--
--用此步是关键把值传递给记录类型的变量中,这样就把输入参数游标与此步是关键所对应的变量及记录变型联系起来了
TYP_REC_1.V_DEPTNO:=TYP_REFCURSOR_2.DEPTNO;
TYP_REC_1.V_DNAME:=TYP_REFCURSOR_2.DNAME;
--管道函数一定要用此句PIPE ROW,后跟要传递的记录变量,即最终显示的变量
PIPE ROW(TYP_REC_1);
END LOOP;
--记:如下的关闭游标与RETURN在LOOP END LOOP之外发生
--用完游标一定要关闭,此和常规的游标操作一样,不然浪费资源
CLOSE TYP_REFCURSOR_1;
--这是管道函数特有的,用于返回控制权给调用方
RETURN;
END;
END PKG_CURSOR;
--包及包体的游标输入参数的函数制作完,下面是测试结果
--有几点注意:
--1,TABLE关键字,用于标记是表函数
--2,TABLE后跟包名.包中的过程或函数,在此为函数
--3,上述函数后是CURSOR,表明输入参数是游标
--4,CURSOR里面就是要传递给游标的结果集,通常是一个SELECT查询,也可以是其它的结果集或其它的表函数
SQL> SELECT * FROM TABLE(PKG_CURSOR.FUNC_IN_CURSOR(CURSOR(SELECT * FROM DEPT)));
V_DEPTNO V_DNAME
---------- --------------
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
--有几点注意:
--1,TABLE关键字,用于标记是表函数
--2,TABLE后跟包名.包中的过程或函数,在此为函数
--3,上述函数后是CURSOR,表明输入参数是游标
--4,CURSOR里面就是要传递给游标的结果集,通常是一个SELECT查询,也可以是其它的结果集或其它的表函数
SQL> SELECT * FROM TABLE(PKG_CURSOR.FUNC_IN_CURSOR(CURSOR(SELECT * FROM DEPT)));
V_DEPTNO V_DNAME
---------- --------------
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS