2012-08-28 74 views
4

我想在程序體內動態創建光標另外我還必須使用代替循環而不是下面的代碼。我做了動態光標,但我不能使用for循環。如何在plsql中創建程序體內的光標

PROCEDURE myprocedure 
AS 
    LV_TEST_CUR SYS_REFCURSOR; 
    LV_QUERY VARCHAR2(200); 
    LV_DATE DATE; 
BEGIN 
    LV_QUERY:='select sysdate as mydate from dual'; 
    OPEN LV_TEST_CUR FOR LV_QUERY; 
    /*FOR CUR_VAR IN LV_TEST_CUR 
    LOOP 
    dbms_output.put_line(CUR_VAR.mydate); 
    end LOOP; 
    */ 
    LOOP 
    FETCH LV_TEST_CUR INTO LV_DATE; 
    EXIT 
    WHEN LV_TEST_CUR%NOTFOUND; 
    DBMS_OUTPUT.PUT_LINE(LV_DATE); 
    END LOOP; 
    CLOSE LV_TEST_CUR; 
END myprocedure; 

如果我使用註釋的代碼(用於環路)中,i得到錯誤

PLS-00221:不是過程或未定義。

是否有可能在動態光標中使用for循環?

回答

6

不能引用遊標變量在遊標FOR循環

,但你可以使用select statment直接:

create or replace PROCEDURE myprocedure 
AS 
    LV_TEST_CUR SYS_REFCURSOR; 
    LV_QUERY VARCHAR2(200); 
    LV_DATE DATE; 
BEGIN 
    FOR CUR_VAR IN (select sysdate as mydate from dual) 
    LOOP 
    dbms_output.put_line(CUR_VAR.mydate); 
    end LOOP; 

END myprocedure; 
/
+0

我認爲這是關於程序的好選擇。它將簡單地代碼 – satheesh

+0

如果我需要在循環內創建多個遊標,該怎麼辦? – Deckard

0

據我所知,你不能用遊標變量或「ref cursor」使用FOR循環。 FOR循環僅用於硬編碼的SQL語句或遊標。請參閱遊標變量限制here的部分,其中明確指出「...您不能在遊標FOR循環中引用遊標變量」。

分享和享受。

+0

小號現在我明白。 – satheesh

1

您不能在動態SQL中使用FOR <row> IN <cursor> LOOP語法;請參閱the example in the documentation,它顯示了您在代碼被註釋掉時使用的方法。

你的例子根本不需要是動態的,但我假設你已經簡化了這個問題。如果它有一個佔位符,那麼無法確定其價值。如果您有:

LV_QUERY:='select sysdate - :days as mydate from dual'; 
FOR CUR_VAR IN LV_TEST_CUR LOOP 
    dbms_output.put_line(CUR_VAR.mydate); 
END LOOP; 

...那麼FOR ... IN ...版本不給你任何地方分配一個值days佔位符。你必須使用動態OPEN做到這一點:

LV_QUERY:='select sysdate - :days as mydate from dual'; 
-- pass '1' as the bind variable 
OPEN LV_TEST_CUR FOR LV_QUERY USING 1; 
LOOP 
    FETCH LV_TEST_CUR INTO LV_DATE; 
    EXIT WHEN LV_TEST_CUR%NOTFOUND; 
    DBMS_OUTPUT.PUT_LINE(LV_DATE); 
END LOOP; 
CLOSE LV_TEST_CUR; 

當然,你可能不需要一個佔位符,只是構建查詢字符串動態,但該限制仍然適用。

+0

是的,你是對的,我簡化了這個問題的代碼。我瞭解循環,我們不能在這種情況下使用 – satheesh