如何使用sysrefcursor PLSQL从过程返回表类型(集合)

时间:2017-08-21 10:14:11

标签: sql oracle plsql oracle12c

我想在过程中使用sysrefcursor返回表类型。 所以我已经定义了记录和表类型:

create or replace TYPE "FILE_RECORD" as object 
( ID NUMBER(30,0), CREATE_DATE  TIMESTAMP(6) );

create or replace TYPE "FILE_TABLE" AS TABLE OF FILE_RECORD;

create or replace TYPE "MSG_RECORD" as object 
( ID    NUMBER(30,0), CREATE_DATE   TIMESTAMP(6) );

create or replace TYPE "MSG_TABLE" AS TABLE OF MSG_RECORD;

写了程序:

   create or replace procedure file_msg
       (i_date IN date,
        o_cur OUT SYS_REFCURSOR)
    AS
    l_file FILE_TABLE;
    l_msg MSG_TABLE;

    BEGIN

      l_file := FILE_TABLE ();
      l_msg := MSG_TABLE ();

      SELECT  FILE_RECORD
             (fi.id,
              fi.create_date )
       BULK COLLECT INTO l_file
       FROM FILES fi
       WHERE fi.create_date between i_date and i_date +1;

       for i in l_file.FIRST..l_file.LAST 
          LOOP
            SELECT  MSG_RECORD
              (me.id,
               me.create_date )
            BULK COLLECT INTO l_msg
            FROM messages me
            WHERE file_id = l_file(i).id;

          END LOOP;

END file_msg; 

那么我现在如何从此过程返回带有sysrefcursor的表类型l_msg和l_file?

我必须使用refcursor而不是真实表中的列来返回表类型(集合),如何解释它:

  

如何存储将返回sysrefcursor的函数的结果?

XING建议的是什么。 我试过这个问题的解决方案,但它对我没有帮助。

2 个答案:

答案 0 :(得分:1)

希望这实际上可以按要求运作。

CREATE OR REPLACE
PROCEDURE file_msg(
    i_date IN DATE,
    o_cur OUT SYS_REFCURSOR,
    P_cure OUT SYS_REFCURSOR)
AS
  l_file FILE_TABLE;
  l_msg MSG_TABLE;
BEGIN
  l_file := FILE_TABLE ();
  l_msg  := MSG_TABLE ();
  SELECT FILE_RECORD (fi.id, fi.create_date) BULK COLLECT
  INTO l_file
  FROM FILES fi
  WHERE fi.create_date BETWEEN i_date AND i_date + 1;
  OPEN P_cure FOR SELECT                         * FROM TABLE(l_file);
  SELECT MSG_RECORD(me.id, me.create_date) BULK COLLECT
  INTO l_msg
  FROM messages me
  WHERE file_id IN
    (SELECT lv.id FROM TABLE(l_file) lv
    );
  OPEN o_cur FOR SELECT * FROM TABLE(l_msg);
END file_msg;
/

答案 1 :(得分:0)

你可以这样做:

 CREATE OR REPLACE PROCEDURE file_msg (i_date   IN     DATE,
                                      o_cur     OUT SYS_REFCURSOR,
                                      P_cure    OUT SYS_REFCURSOR)
  AS
   l_file   FILE_TABLE;
   l_msg    MSG_TABLE;
BEGIN
   l_file := FILE_TABLE ();
   l_msg := MSG_TABLE ();

   SELECT FILE_RECORD (fi.id, fi.create_date)
     BULK COLLECT INTO l_file
     FROM FILES fi
    WHERE fi.create_date BETWEEN i_date AND i_date + 1;

   Open P_cure for select * from table(l_file);

   FOR i IN l_file.FIRST .. l_file.LAST
   LOOP
      SELECT MSG_RECORD(me.id, me.create_date)
        BULK COLLECT INTO l_msg
        FROM messages me
       WHERE file_id = l_file(i).id;
   END LOOP;

   Open o_cur for select * from table(l_msg);

END file_msg;