2017-03-09 79 views
3

我正在使用Oracle 12c。在PL/SQL我可以做到这一点PL SQL for循环Sys_RefCursor

set serveroutput on 
declare 
begin 
    for x in (select 1 as y from dual) loop 
    dbms_output.put_line(x.y); 
    end loop; 
end; 

我也能做到这一点...

set serveroutput on 
declare 
    cursor c1 is 
    select 1 as y from dual; 
begin 
    for x in c1 loop 
    dbms_output.put_line(x.y); 
    end loop; 
end; 

到目前为止,一切都很好。但我可以用sys_refcursor来做到这一点吗?我知道我可以取回/ while循环做,但更喜欢for循环的语法(我认为这是有很多清洁)...

set serveroutput on 
declare 
    cur sys_refcursor; 
begin 
    cur := Package.GetData(1234); 
    fetch cur into y; 
    while cur%FOUND loop 
    dbms_output.put_line(y); 
    fetch cur into y; 
    end loop; 
end; 

我想做...

set serveroutput on 
declare 
    cur sys_refcursor; 
begin 
    cur := PACKAGE.GetData(1234); -- This returns a sys_refcursor 
    for x in cur loop 
    dbms_output.put_line(x.y); 
    end loop; 
end; 

Error report - 
ORA-06550: line 5, column 16: 
PLS-00221: 'cur' is not a procedure or is undefined 

是否有通过sys_refcursor进行循环的机制(而不是通过fetch进入/ while循环)?也许在12c中有一些我不知道的新东西...?

+2

我不这么认为;但是fetch/while循环有什么问题? –

+1

你绝对需要使用ref cursor吗? IME,在PL/SQL中工作时很少需要引用游标 - 主要用途是将游标指针传递给非PL/SQL程序,以便它们可以循环,就好像它们自己打开游标一样。 – Boneist

+0

是因为弱类型引用游标([因为%rowtype不起作用](http://stackoverflow.com/q/11187376/266304))而无法声明记录的问题,无论是因为您不想声明一个记录类型或不知道它将包含什么? 'x.y'参考文献表明你至少知道一些领域? –

回答

2

SYS_REFCURSOR只是一个预先声明的弱引用游标。没有这样的机制可以通过sys_refcursor循环而不用提取。你也不能比较弱的refcursor与正常的光标,他们的工作方式不同。这是一个缓冲空间,它被分配来暂时保存结果。当您在PLSQL块运行下面的语句,PLSQL引擎不列入明白一个PLSQL变量,引发错误

对于x在CUR环

PLS-00221: 'CUR' is not a procedure or is undefined 

除了下面的语句,因为也将失败如果重新编号为SYS_REFCURSOR,您没有定义OUT参数。

cur:= PACKAGE.GetData(1234);

您可以获取SYS_REFCURSOR的内容,然后下面显示出来:

declare 
    a SYS_REFCURSOR; 
    v_emp_id employee.emp_id%type; 
begin   
    --- This is a procedure with OUT parameter as SYS_REFCURSOR 
    dynmc_selec(emp_output=>a); 

    loop 
    FETCH a INTO v_emp_id; 
    EXIT WHEN a%NOTFOUND; 
    DBMS_OUTPUT.PUT_LINE(v_emp_id); 

    end loop; 
end; 
+0

弱引用游标和普通游标的工作方式可能不同,但我曾想过Oracle会提供一些语法糖允许我将其中一个用作for循环中的另一个。 也就是说,如果不能做到,那就是答案。 – 0909EM