2014-05-09 39 views
0

從函數返回時,我在從PL/SQL中的打開ref_cursor中提取時遇到問題。當我在函數的主體中放置完全相同的讀取語句來代替返回語句時,它可以正常工作。Oracle函數 - 從返回的提取ref_cursor - ORA-01001:無效光標

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

有人能幫我弄清楚我在這裏做錯了嗎?

+1

將'GetBound'的返回類型更改爲'sys_refcursor'並查看是否有幫助。 –

回答

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; 
0

我不認爲你已經在這裏提供了你的會話的確切內容,否則你不會設法創建你的函數的第二個版本,沒有編譯錯誤,因爲沒有return語句。

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