Oracle PL/SQL 将游标(从函数)中的每个值逐一分配给另一个游标

Oracle PL/SQL Assign each value from a cursor(from function) to another cursor one by one

我有一个名为 GET_CLIENT_IN_SED(return sys_refcursor) 的函数,它给了我一个 ID 号列表(单列)。现在,在一个过程中,我试图遍历每个(一个接一个)值并将其用于调用第二个过程(它需要一个客户端 ID 参数)。

PROCEDURE GET_ORDINARY_CLIENT;

PROCEDURE GET_ORDINARY_CLIENT_BY_SED
  ( sed_in IN varchar2, client_sed OUT SYS_REFCURSOR )
IS
   ordinary_clients sys_refcursor;

BEGIN
  ordinary_clients := GET_CLIENT_IN_SED(sed_in);
  for item in ordinary_clients loop
    client_sed := client_sed + ordinary_clients(i);
  end loop;
END;

遍历引用游标不同于遍历数组或 table 这解释了为什么你的 FOR...LOOP 不起作用。

简而言之,ref_cursor 不是集合,更像是集合的 "pointer" 或 "iterator"。在另一个问题中,您会发现一个非常清楚的示例,该示例使用 FETCH.

遍历 ref_cursor

How to use record to loop a ref cursor?

您的数据示例如下所示:

PROCEDURE GET_ORDINARY_CLIENT_BY_SED(sed_in     IN VARCHAR2,
                                     client_sed OUT SYS_REFCURSOR) IS
   ordinary_clients SYS_REFCURSOR;
   clt              NUMBER; -- assuming your cursor contains strictly numbers
BEGIN
   ordinary_clients := GET_CLIENT_IN_SED(sed_in);
   LOOP
      FETCH ordinary_clients
         INTO clt;
      EXIT WHEN ordinary_clients%NOTFOUND;
      dbms_output.put_line(clt);
      -- do some other things here with your number
   END LOOP;
END;

据我所知,您需要执行以下操作:

函数:

此函数将输入为数字,return 为一个引用。与您的要求相似。

CREATE OR REPLACE FUNCTION get_num_sysrefcur (num IN NUMBER)
   RETURN SYS_REFCURSOR
AS
   my_cursor   SYS_REFCURSOR;
BEGIN
   --
   OPEN my_cursor FOR
      WITH ntable
           AS (SELECT 1 ID, 111 AGT, 'ABC' DESCRIP FROM DUAL
               UNION ALL
               SELECT 2 ID, 222 AGT, 'ABC' DESCRIP FROM DUAL
               UNION ALL
               SELECT 1 ID, 333 AGT, 'ABC' DESCRIP FROM DUAL)

         SELECT AGT FROM ntable WHERE ID = num;


   RETURN my_cursor;
END;
/

阻止(在您的情况下为程序) -- 这个匿名块将循环遍历 sys_refcursor 中的记录 return。类似于您希望第二个过程使用 sys_refcursor 的值并循环它的地方(您可以创建过程来代替这个匿名块)。

DECLARE
   a   NUMBER := 1;

   TYPE ta IS TABLE OF NUMBER
      INDEX BY PLS_INTEGER;
   b   ta;
   x   SYS_REFCURSOR;
BEGIN
   x := get_num_sysrefcur (a);

  fetch x bulk collect into b;

  for i in 1..b.count
  loop
   -- Displaying the result of the ref_cursor.
   DBMS_OUTPUT.put_line (b(i));
  end loop;
END;