存储过程如何从多个游标返回

时间:2017-06-08 10:25:10

标签: sql oracle stored-procedures

我下面有Oracle存储过程,除了过程调用者从不同游标获取所有值的部分之外,我理解了大部分内部逻辑。

有些读取SP会在下面的示例中显示的过程参数中返回OUT部分。但我没有得到任何关于p_returnCode如何存储来自存储过程内的查询的结果集的参考。

过程retrieveX(p_date日期,p_loc varchar2,p_returnCode out整数)

下面的存储过程有3个游标cur1,cur2和cur3。它如何或在何处存储值? Cur1包含2列多行,Cur2和Cur3包含一列多行。 任何人都可以澄清这一部分吗?

来自cgi脚本的来电者

report.retrieveX(p_date,p_loc,p_return)

完整存储过程

PROCEDURE retrieveX(
    p_date DATE,
    p_loc VARCHAR2,
    p_returnCode OUT INTEGER
)
AS

    TYPE cur_typ IS REF CURSOR;
    cur1 cur_typ;
  cur2 cur_typ;
  cur3 cur_typ;
    query_str VARCHAR2(2000) := '';
    query_str2 VARCHAR2(2000) := '';
    query_str3 VARCHAR2(2000) := '';
    v_an VARCHAR2(20);
    v_tn VARCHAR2(20);
    v_sOID varchar2(20);

BEGIN

sqlRouteDT := 'AND  sp.ROUTE_DT = TO_DATE(''' || TO_CHAR(p_date, 'YYYY/MM/DD') || ''',''YYYY/MM/DD'')';

IF p_loc IS NOT NULL THEN
  sqlLocation := 'AND   act.location_cd = ''' || p_loc || '''';
END IF;

    p_returnCode := 0;
    query_str := '
                    SELECT distinct
                       sp.ab,
                       y.track,
                    FROM ship sp
                       inner join activ act on sp.soid=act.on
                       inner join peace y on act.on=y.soid
          where
             sp.man is not null
             ' || sqlLocation || '
             ' || sqlRouteDT || '
                    ORDER BY sp.ab asc
        ';
    OPEN cur1 FOR query_str1;
    LOOP
      FETCH cur1
      INTO
        v_AN,
        v_FN
      EXIT WHEN cur1%NOTFOUND;

      query_str2 := '
        SELECT DISTINCT INTER_CD
        FROM    TBL_INTR
        WHERE   AF = ''Y''
          AND   sOID = ''' || v_sOID || '''
        ORDER BY INTER_CD
        ';
      OPEN cur2 FOR query_str2;
      LOOP
        FETCH   cur2
        INTO    v_intr_cd;
        EXIT WHEN cur2%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('INTER_CD|' || v_intr_cd);
      END LOOP;
      CLOSE cur2;

      query_str3 := '
        SELECT DISTINCT hi_cd
        FROM    tbl_hi
        WHERE   AF = ''Y''
          AND   sOID = ''' || v_sOID || '''
        ORDER BY    hi_cd
        ';
      OPEN cur3 FOR query_str3;
      LOOP
        FETCH   cur3
        INTO    v_hi_c;
        EXIT WHEN cur3%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('hi_cd|' || v_hi_c);
      END LOOP;
      CLOSE cur3;
    END LOOP;
    CLOSE cur1;
EXCEPTION   WHEN OTHERS THEN
    p_returnCode := 1;
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
END retrieveX;

1 个答案:

答案 0 :(得分:0)

我认为不可能做你想做的事。

也许您应该考虑使用流水线功能,请查看https://oracle-base.com/articles/misc/pipelined-table-functions

使用这种技术,您可以编写一个pl / sql代码来访问复杂的数据和关系表,并将结果作为一个简单的

 select * from StoredProcedure(Parameter_1...);