存储过程内以不同参数多次调用以SYS_REFCURSOR返回结果集的存储过程,数据竟然不变化。

时间:2021-04-27 22:54:35
同一package内,两个存储过程:
--被调用的过程
  PROCEDURE RPT_A(
        P_DATE VARCHAR2
        ,P_CUR OUT SYS_REFCURSORR) 
      IS
    BEGIN
      OPEN P_CUR FOR
           SELECT * FROM TABLE1 WHERE MYDATE=P_DATE;
    END;

--调用的过程
  PROCEDURE RPT_B(
        P_DATE_1 VARCHAR2
        ,P_DATE_2 VARCHAR2
        ,P_DATE_3 VARCHAR2
        ,P_CUR_1 OUT SYS_REFCURSOR
        ,P_CUR_2 OUT SYS_REFCURSOR
        ,P_CUR_3 OUT SYS_REFCURSOR) 
      IS
    BEGIN
      RPT_A(P_DATE_1,P_CUR_1);
      RPT_A(P_DATE_2,P_CUR_2);
      RPT_A(P_DATE_3,P_CUR_3);
    END;

现在执行RPT_B,分别输入P_DATE_1、P_DATE_2、P_DATE_3以不同的值,3个SYS_REFCURSOR返回的结果竟然完全一样。而实际上查询数据是不一样的。
分别直接执行RPT_A,输入不同的P_DATE参数,结果也是不一样的。
问题出在哪儿?难道前面执行返回的SYS_REFCURSOR的值会被之后执行返回的值覆盖吗?

3 个解决方案

#1


PROCEDURE RPT_A(
        P_DATE VARCHAR2
        ,P_CUR OUT SYS_REFCURSORR) 
      IS
    BEGIN
      OPEN P_CUR FOR
           SELECT * FROM TABLE1 WHERE MYDATE=P_DATE;
    END;
中SYS_REFCURSORR 多了一个R,这应该是手误。我是这么测试的,没有问题,每次可以取到不同的值,你可以参考一下:
declare
v_rent_rows1 SYS_REFCURSOR;
v_rent_rows2 SYS_REFCURSOR;
v_rent_rows3 SYS_REFCURSOR;
v_rent_row A%rowType;
begin
RPT_B(1,2,3,v_rent_rows1,v_rent_rows2,v_rent_rows3);
loop
fetch v_rent_rows1 into v_rent_row;
exit when v_rent_rows1%NOTFOUND;
Dbms_output.put_line(v_rent_row.HEADINDEX||' '||v_rent_row.tailindex);
end loop;
close v_rent_rows1;
--
loop
fetch v_rent_rows2 into v_rent_row;
exit when v_rent_rows2%NOTFOUND;
Dbms_output.put_line(v_rent_row.HEADINDEX||' '||v_rent_row.tailindex);
end loop;
close v_rent_rows2;
--
loop
fetch v_rent_rows3 into v_rent_row;
exit when v_rent_rows3%NOTFOUND;
Dbms_output.put_line(v_rent_row.HEADINDEX||' '||v_rent_row.tailindex);
end loop;
close v_rent_rows3;
end;
----------
create or replace procedure  RPT_A(
        P_DATE VARCHAR2
        ,P_CUR OUT SYS_REFCURSOR) 
      IS
    BEGIN
      OPEN P_CUR FOR
           SELECT * FROM A WHERE ID=P_DATE;
    END;
----------
create or replace procedure RPT_B(
        P_DATE_1 VARCHAR2
        ,P_DATE_2 VARCHAR2
        ,P_DATE_3 VARCHAR2
        ,P_CUR_1 OUT SYS_REFCURSOR
        ,P_CUR_2 OUT SYS_REFCURSOR
        ,P_CUR_3 OUT SYS_REFCURSOR) 
      IS
    BEGIN
      RPT_A(P_DATE_1,P_CUR_1);
      RPT_A(P_DATE_2,P_CUR_2);
      RPT_A(P_DATE_3,P_CUR_3);
    END;

我觉得你是最后读取值的时候,读取的同一个SYS_REFCURSOR~

#2


这个应该不会,建议 LZ 把测试过程也列一下;

#3


感谢两位回复。问题不在这里,问题出在查询的VIEW,通过包给它传参数导致的。

#1


PROCEDURE RPT_A(
        P_DATE VARCHAR2
        ,P_CUR OUT SYS_REFCURSORR) 
      IS
    BEGIN
      OPEN P_CUR FOR
           SELECT * FROM TABLE1 WHERE MYDATE=P_DATE;
    END;
中SYS_REFCURSORR 多了一个R,这应该是手误。我是这么测试的,没有问题,每次可以取到不同的值,你可以参考一下:
declare
v_rent_rows1 SYS_REFCURSOR;
v_rent_rows2 SYS_REFCURSOR;
v_rent_rows3 SYS_REFCURSOR;
v_rent_row A%rowType;
begin
RPT_B(1,2,3,v_rent_rows1,v_rent_rows2,v_rent_rows3);
loop
fetch v_rent_rows1 into v_rent_row;
exit when v_rent_rows1%NOTFOUND;
Dbms_output.put_line(v_rent_row.HEADINDEX||' '||v_rent_row.tailindex);
end loop;
close v_rent_rows1;
--
loop
fetch v_rent_rows2 into v_rent_row;
exit when v_rent_rows2%NOTFOUND;
Dbms_output.put_line(v_rent_row.HEADINDEX||' '||v_rent_row.tailindex);
end loop;
close v_rent_rows2;
--
loop
fetch v_rent_rows3 into v_rent_row;
exit when v_rent_rows3%NOTFOUND;
Dbms_output.put_line(v_rent_row.HEADINDEX||' '||v_rent_row.tailindex);
end loop;
close v_rent_rows3;
end;
----------
create or replace procedure  RPT_A(
        P_DATE VARCHAR2
        ,P_CUR OUT SYS_REFCURSOR) 
      IS
    BEGIN
      OPEN P_CUR FOR
           SELECT * FROM A WHERE ID=P_DATE;
    END;
----------
create or replace procedure RPT_B(
        P_DATE_1 VARCHAR2
        ,P_DATE_2 VARCHAR2
        ,P_DATE_3 VARCHAR2
        ,P_CUR_1 OUT SYS_REFCURSOR
        ,P_CUR_2 OUT SYS_REFCURSOR
        ,P_CUR_3 OUT SYS_REFCURSOR) 
      IS
    BEGIN
      RPT_A(P_DATE_1,P_CUR_1);
      RPT_A(P_DATE_2,P_CUR_2);
      RPT_A(P_DATE_3,P_CUR_3);
    END;

我觉得你是最后读取值的时候,读取的同一个SYS_REFCURSOR~

#2


这个应该不会,建议 LZ 把测试过程也列一下;

#3


感谢两位回复。问题不在这里,问题出在查询的VIEW,通过包给它传参数导致的。