2017-09-05 54 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