2011-05-17 75 views
0

我在我的办公室运行Oracle 9i服务器。我正在处理一个将sys_refcursor作为out参数传递给另一个包(以及其他参数)的过程。我能够将类型定义为被调用过程在游标中返回的各个列的记录。然后我可以用这样的代码循环:从存储过程中的sys_refcursor获取特定字段?

LOOP 
    fetch o_results into v_rec; 
    exit when o_results%notfound; 
    dbms_output.put_line(v_rec.some_id); 
end loop; 

有没有办法只拉一列而不必声明整个rowtype?我试过类似的东西:

LOOP 
    fetch o_results.some_id into v_id; 
    exit when o_results%notfound; 
    dbms_output.put_line(v_id); 
end loop; 

但这并不奏效。任何其他想法?

回答

1

不,如果游标返回一个包含多列的结果集,则不能将单个列读取到记录以外的局部变量中。但是,您确实有几个选择。

如果声明强类型的游标而不是弱类型的游标,则可以根据该游标定义声明局部变量,而不是声明新的集合。

create or replace procedure cursor_proc 
as 
    cursor emp_cur 
     is 
    select empno, ename 
    from emp; 
    l_row emp_cur%rowtype; 
begin 
    open emp_cur; 
    loop 
    fetch emp_cur into l_row; 
    exit when emp_cur%notfound; 
    dbms_output.put_line(l_row.ename); 
    end loop; 
    close emp_cur; 
end; 

或者,如果你知道弱类型REF光标总是返回特定对象中的所有列,可以锚您的局部变量声明到该对象。你总是可以通过声明一个你的光标从中选择的视图来完成这项工作。例如

create or replace view vw_emp 
as 
select ename, empno 
    from emp 

create or replace procedure cursor_proc2 
as 
    emp_cur sys_refcursor; 
    l_row vw_emp%rowtype; 
begin 
    open emp_cur for select * from vw_emp; 
    loop 
    fetch emp_cur into l_row; 
    exit when emp_cur%notfound; 
    dbms_output.put_line(l_row.ename); 
    end loop; 
    close emp_cur; 
end; 

最后,如果您使用的是隐式游标,Oracle将隐式声明的集合类型

create or replace procedure cursor_proc3 
as 
begin 
    for emp in (select ename, empno from emp) 
    loop 
    dbms_output.put_line(emp.ename); 
    end loop; 
end;