日期:2014-05-17  浏览次数:20872 次

***Oracle存储过程是否能够直接返回游标类型?***
在Informix数据库中,可以将在存储过程中查询到的多条记录以一个游标的形式返回出去,请问Oracle中有这样的功能吗?如何来做?

如果不能,那么请问Oracle存储过程如何返回多条记录?

------解决方案--------------------
我的异常网推荐解决方案:oracle存储过程,http://www.aiyiweb.com/oracle-develop/177537.html
------解决方案--------------------
--当然可以了,网上很多例子
CREATE OR REPLACE PROCEDURE ll_02 (p_cursor OUT sys_refcursor) IS
BEGIN
OPEN p_cursor FOR
SELECT * from tablename;
END ll_02;
/
------解决方案--------------------
我知道的有两种方法:
1、用过程实现
2、用函数实现

法1:有两种方式 a b

a、建包并在包体内的过程中实现
eg:
create or replace package pkg_test as
type t_ref is ref cursor;
procedure p_test(cur_ref out t_ref);
end pkg_test;
/

create or replace package body pkg_test as
procedure p_test(cur_ref out t_ref) is
begin
open cur_ref for select employee_name from employee;
end p_test;
end pkg_test;
/

b、不用建包,直接用一个存储过程,但要事先定义一个包“规范”(我叫它包头)
create package pack1
as
type c_u_r is ref cursor;
end;
/

create or replace procedure test_1(table_cursor out pack1.c_u_r)
AS
begin
Open table_cursor for select employee_name from employee;
end test_1;
/


法2: 这样我用过的是用建包实现(不一定!)
CREATE OR REPLACE PACKAGE GET_EMP AS
TYPE emp_name IS REF CURSOR;
FUNCTION get_emp_name(L_ID IN VARCHAR2) RETURN emp_name;
END GET_EMP;
/

CREATE OR REPLACE PACKAGE BODY GET_EMP AS
FUNCTION get_emp_name(L_ID IN VARCHAR2) RETURN emp_name
IS w_emp_name
emp_name;
BEGIN
OPEN w_emp_name FOR
SELECT EMPLOYEE_NAME FROM EMPLOYEE WHERE TASK_ID=L_ID;
RETURN w_emp_name;
END get_emp_name;
END GET_EMP;
/


上面都是我跑过通了的,法一的b改了一下,还没跑,因该没问题
调用时函数用附值,过程直接用。



------解决方案--------------------
接着我上面的帖子,这里是调用上面过程和函数的过程(其中法二有点繁,没改,你主要看下怎么调用,我加了红色,不知能显示出来否)


法1 a :

create or replace procedure test_pkg_test as
TEST pkg_test.t_ref;
L_NAME VARCHAR2(20);
BEGIN
pkg_test.p_test(TEST, '1 ');
LOOP
FETCH TEST INTO L_NAME;
EXIT WHEN TEST%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(L_NAME|| ', ');
END LOOP;
END test_pkg_test;
/

法二:

CREATE OR REPLACE PROCEDURE SHOWDEPT AS
CURSOR T_ID IS SELECT DISTINCT TASK_ID FROM EMPLOYEE ORDER BY TASK_ID;
L_ID EMPLOYEE.TASK_ID%TYPE;
L_NAME VARCHAR2(30);
TO_NAMES VARCHAR2(30);
A_STEPWORKTIME NUMBER :=0;
TEST GET_EMP.EMP_NAME; --这句
BEGIN
OPEN T_ID;
< <LOOP1> >
LOOP
FETCH T_ID INTO L_ID;
EXIT WHEN T_ID%NOTFOUND;
SELECT SUM(STEPWORKTIME) INTO A_STEPWORKTIME FROM EMPLOYEE WHERE TASK_ID=L_ID;
TEST := GET_EMP.GET_EMP_NAME(L_ID); --还有这句
TO_NAMES := ' ';
< <LOOP2> >
LOOP
FETCH TEST INTO L_NAME;
EXIT WHEN TEST%NOTFOUND;
TO_NAMES := TO_NAMES|| ', '||L_NAME;
END LOOP LOOP2;
INSERT INTO GET_EMPLOYEE VALUES(L_ID,TO_NAMES,A_STEPWORKTIME);
COMMIT;
END LOOP LOOP1;
CLOSE T_ID;
END SHOWDEPT;
/