0

从函数返回时,我无法从 PL/SQL 中的打开的 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

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

4

2 回答 2

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;
于 2014-08-25T05:34:59.040 回答
0

我认为您没有在此处提供会话的确切内容,否则您将无法在没有编译错误的情况下创建函数的第二个版本,因为没有返回语句。

只要ref_cursor已由 PL/SQL 中的 TYPE 语句声明,我认为将其用作函数的返回类型没有任何问题。以下是使用 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> 
于 2014-05-10T11:23:41.017 回答