2017-10-03 42 views
-2

私はクエリが存在するクエリのセットを持っています。 は、今私は、以下に示すように、FORALL使用してこれを実行したい:forall内でクエリを実行する

open EX01_CURSOR; 

LOOP 
    FETCH EX01_CURSOR BULK COLLECT INTO Queries LIMIT 50000; 
    EXIT WHEN Queries.COUNT = 0; 
    FORALL i IN 1 .. Queries.count 
    **execute immediate Queries(i).update_query;** 
    commit; 

END LOOP; 

close EX01_CURSOR; 

私はFORALLブロック内の私のクエリを実行します。以下に示すように 私はコンパイルエラーを取得しています:

のIn-BIND BULKなしのDML文はFORALL

内では使用できません誰かが助けてくださいすることができますか?

+1

言語/技術にタグを付けてください。彼らは何を見ているのか分からないと、どうやって助けてくれるのですか?それ以上をSOに転記する前にこれをお読みください:https://stackoverflow.com/help/asking –

+0

参照https://stackoverflow.com/questions/27814535/getting-error-pls-00435-dml-statement-without-バルクインバインド - 使用不可 - 内部 –

答えて

0

FORALLは、実際にはLOOPまたはイテレータではありませんが、BULKDMLの操作です。これは、コレクション内のエントリごとに操作を実行しませんが、コレクション内のすべてのエントリに対して1つのDML操作を実行します。 Dynamic SQLBULKに実行することはできず、反復できません。 EXECUTE IMMEDIATEを繰り返し実行するには、LOOPを使用する必要があります(または別の方法をとる)。

例を示します。コミットサイズを制御するのにまだBULK COLLECTが使用されますが、FOR LOOPにはDynamic SQLがあります。 (注意:動的SQLのこのボリュームを行うことは効率的ではない単なる例あなたの元のコレクションのサイズを維持する。)

は、テストデータの設定:

CREATE TABLE TEST_TABLE (
    TEST_ID NUMBER 
); 
INSERT INTO TEST_TABLE SELECT LEVEL 
         FROM DUAL 
         CONNECT BY LEVEL <= 50001; 

初期データ:次に

SELECT * FROM TEST_TABLE ORDER BY 1 DESC FETCH FIRST 5 ROWS ONLY; 
TEST_ID 
50001   
50000   
49999   
49998   
49997  

実行をブロック。これはFORALLBULK DMLを使用しません。これは、代わりに使用していますFOR LOOP

DECLARE 

    CURSOR EX01_CURSOR IS (
    SELECT 'UPDATE TEST_TABLE SET TEST_TABLE.TEST_ID = TEST_TABLE.TEST_ID + 100000 WHERE TEST_TABLE.TEST_ID = ' || 
      TEST_TABLE.TEST_ID AS UPDATE_QUERY 
    FROM TEST_TABLE); 

    TYPE EX01_CUR_TYPE IS TABLE OF EX01_CURSOR%ROWTYPE; 
    QUERIES EX01_CUR_TYPE; 

BEGIN 
    QUERIES := EX01_CUR_TYPE(); 

    OPEN EX01_CURSOR; 

    LOOP 
    FETCH EX01_CURSOR BULK COLLECT INTO QUERIES LIMIT 50000; 
    EXIT WHEN QUERIES.COUNT = 0; 

    FOR UPDATE_POINTER IN 1..QUERIES.COUNT 
    LOOP 
     EXECUTE IMMEDIATE QUERIES(UPDATE_POINTER).UPDATE_QUERY; 
    END LOOP; 
    COMMIT; 

    END LOOP; 

    CLOSE EX01_CURSOR; 
END; 
/

PL/SQL procedure successfully completed. 

結果:

SELECT * FROM TEST_TABLE ORDER BY 1 DESC FETCH FIRST 5 ROWS ONLY; 
TEST_ID 
150001 
150000 
149999 
149998 
149997 
関連する問題