Oracle函数 - 从返回的ref_cursor获取 - ORA-01001:无效的游标

时间:2014-05-09 06:55:52

标签: sql plsql oracle10g cursor ref-cursor

从函数返回时,我无法从PL / SQL中的open ref_cursor中获取。当我在函数体中放置完全相同的fetch语句来代替return语句时,它工作正常。

function GetBound(p_lat in number, p_long in number) return ref_cursor
IS
v_rc_ref_cursor sys_refcursor;
BEGIN

open v_rc_ref_cursor for select * from state_bound;
return v_rc_ref_cursor;

END;

现在,如果我从匿名plsql块调用它,我会收到错误“ORA-01001:无效游标”

    DECLARE

    v_rc_ref_cursor sys_refcursor;
    v1 number(38);
    v2 varchar2(50);
    v3 number(38);
    v4 varchar2(50);
    BEGIN

    v_rc_ref_cursor := GetBound(122.0928,-18.6974);

    fetch v_rc_ref_cursor into v1, v2, v3, v4;
    close v_rc_ref_cursor;
    DBMS_OUTPUT.PUT_LINE(v1 || v2 || v3 || v4);

    END;

但是,如果我将匿名块放入实际功能中,则一切正常。见下文:

function GetBound(p_lat in number, p_long in number) return ref_cursor
IS

v_rc_ref_cursor sys_refcursor;
v1 number(38);
v2 varchar2(50);
v3 number(38);
v4 varchar2(50);

BEGIN

open v_rc_ref_cursor for select * from state_bound;
-- return v_rc_ref_cursor;

fetch v_rc_ref_cursor into v1, v2, v3, v4;
close v_rc_ref_cursor;
DBMS_OUTPUT.PUT_LINE(v1 || v2 || v3 || v4);

END;

我已经阅读并发现了一些人在做我在这里所做的事情的例子,所以据我所知这应该有效。例如。 https://community.oracle.com/thread/888365

有人可以帮我弄清楚我在这里做错了吗?

2 个答案:

答案 0 :(得分:0)

我不认为您已在此处提供了会话的确切内容,否则您将无法创建函数的第二个版本而不会出现编译错误,因为没有返回语句。< / p>

只要您的PL / SQL中的TYPE语句声明了 ref_cursor ,我就不会发现使用它作为函数返回类型的任何问题。以下是使用hr.employees示例表的类似示例:

--
set serveroutput on
--
<<bk1>>
declare
    type ref_cursor is ref cursor;
-- 
    fname   hr.employees.first_name%type;
    empCur  sys_refcursor;
-- 
    function testFun
    (
        p_depid in hr.employees.department_id%type
    )
    return ref_cursor
    is
    begin
        <<bk2>>
        declare
            empCur sys_refcursor;
        begin
            open
                bk2.empCur
            for
                select
                    t1.first_name
                from
                    hr.employees t1
                where
                    t1.department_id = p_depid;
    --         
    -- 
            return bk2.empCur;
        end;
    end testFun;
begin
    bk1.empCur := bk1.testFun(p_depid => 100);
--     
    loop
        fetch
            bk1.empCur
        into
            bk1.fname;
--             
        exit when bk1.empCur%notfound;
--         
        sys.dbms_output.put_line('fname = ' || bk1.fname);
    end loop;
--     
    close bk1.empCur;
end;
/
--
show errors;
--     
set serveroutput off

输出

No errors.
fname = Nancy
fname = Daniel
fname = John
fname = Ismael
fname = Jose Manuel
fname = Luis

PL/SQL procedure successfully completed.


SQL> 

答案 1 :(得分:0)

我最终解决此问题的方法是将返回类型从ref_cursor更改为sys_refcursor。这似乎是一种修复它的愚蠢方式,但它适用于这种变化。代码:

function GetBound(p_lat in number, p_long in number) return sys_refcursor
IS
v_rc_ref_cursor sys_refcursor;
BEGIN

open v_rc_ref_cursor for select * from state_bound;
return v_rc_ref_cursor;

END;