【问题标题】:Oracle Function - Fetch From Returned ref_cursor - ORA-01001: invalid cursorOracle 函数 - 从返回的 ref_cursor 中获取 - ORA-01001:游标无效
【发布时间】:2014-05-09 06:55:52
【问题描述】:

当从函数返回时,我无法从 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: invalid cursor”

    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

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

【问题讨论】:

  • 把GetBound的返回类型改成sys_refcursor看看有没有帮助。

标签: sql plsql oracle10g cursor ref-cursor


【解决方案1】:

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

只要 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> 

【讨论】:

    【解决方案2】:

    我最终解决此问题的方法是将返回类型从 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;
    

    【讨论】:

      猜你喜欢
      • 2013-06-09
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多