2017-09-05 26 views
0

我有一个名为GET_CLIENT_IN_SED(返回sys_refcursor)的函数,它给了我一个id号列表(单列)。现在,在一个过程中,我试图循环遍历每个值(一个接一个),并用它来调用第二个过程(它需要一个客户端ID参数)。Oracle PL/SQL将游标(从函数)中的每个值逐个分配给另一个游标

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; 

回答

1

据我可以理解你需要做的是这样的:

功能:

该函数将输入为数字并返回一个refcursor。与您的要求类似。

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返回。与您相似,您需要第二个过程使用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; 
+0

批量收集是我喜欢使用的另一种有效方法(我发现使用集合比使用游标更简单!)。虽然最好不要在数据量非常大时使用,因为它存储在变量中而不是迭代器中。 – Dessma

+0

@Dessma您也可以使用批量收集进行迭代。您有限制条款限制数据选择,您可以迭代所有记录 – XING

1

要循环访问游标不像循环访问数组或表,这就解释了为什么您的FOR ... LOOP不起作用。

简而言之,而不是一个集合,ref_cursor更像是一个集合上的“指针”或“迭代器”。在这个其他问题中,你会发现一个使用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; 
+0

我并不想从表中加载,我试图从SYS_REFCURSOR返回功能加载,因为我没有存储在任何表中的值,有关如何获取的值只说明。所以我不能使用table_name%ROWTYPE – miMescua

+0

对不起,我假设你的'普通客户'光标包含一个“复杂”类型,如表行。如果你的refcursor只包含简单的数据,例如数字,你可以将它们放入一个适当类型的简单变量中,并以相同的逻辑使用它们。我将用其他信息编辑我的答案。 – Dessma