2017-02-08 8 views
1

以下にあるFORALL文に挿入された行の数を取得して出力する最良の方法は何ですか?私はSQL%BULK_ROWCOUNTを見たことがありますが、以下のステートメントではどのように動作するのか分かりません。Oracle PL/SQL FORALL文に挿入された挿入数はどのように出力されますか

それは

DBMS_OUTPUT.('rows inserted '||SQL%BULK_ROWCOUNT||''); 

では、別のFORALL文で行くには上記の必要性をしていますか?以下のコードについては、これをどうすれば達成できますか?

DECLARE 
    TYPE t_arc_act_plus_trigger1 IS TABLE OF arc_act_plus_triggers1%ROWTYPE; 
    v_arc_act_plus_triggers1 t_arc_act_plus_trigger1; 

    CURSOR c_arc_act_plus_triggers1 IS 
     SELECT /*+ PARALLEL */ apt.* 
     FROM act_plus_triggers1 apt 
     WHERE NOT EXISTS 
       (SELECT 1 
        FROM act_plus_triggers_copy1 aptc 
        WHERE aptc.surr_id = apt.surr_id) 
     AND apt.status IN ('EXT', 'EXP'); 
BEGIN 

    OPEN c_arc_act_plus_triggers1; 
    LOOP 
     FETCH c_arc_act_plus_triggers1 BULK COLLECT INTO v_arc_act_plus_triggers1 LIMIT 10000; -- limit to 10k to avoid out of memory 

     FORALL i IN 1..v_arc_act_plus_triggers1.COUNT 
     INSERT /*+ APPEND_VALUES */ INTO arc_act_plus_triggers1 values v_arc_act_plus_triggers1(i); 


     Com0932.get_parameter ('ACT_ARCHIVE_TRIGGER_STOP_YN',l_STOP_PROGRAM_YN);   
     IF l_STOP_PROGRAM_YN = 'Y' THEN 
      p_location('insert_into_arc_act_plus - STOP_PROGRAM_YN flag = '||l_STOP_PROGRAM_YN||' so ROLLBACK'); 
      ROLLBACK; 
      EXIT; 
     END IF; 

     -- ************************************************** 
     -- Output how many records have been inserted here??? 
     -- ************************************************** 

     -- commit after every 10000 records into arc_act_plus_triggers1 
     COMMIT;  
     EXIT WHEN c_arc_act_plus_triggers1%NOTFOUND; 


    END LOOP; 
    CLOSE c_arc_act_plus_triggers1; 

END; 
+1

「SQL%ROWCOUNT」を試しましたか? https://docs.oracle.com/database/121/LNPLS/static.htm#LNPLS99956 –

+1

おそらく、それは 'v_arc_act_plus_triggers1.COUNT'でしょうか?例外が発生しないと仮定した場合など – Boneist

+0

ある表からコピー表であるアーカイブ表へのまっすぐなコピーであるため、例外は発生しません。 –

答えて

0

私は「不足しているセミコロンのタイプのエラー」を許してくださいそうに対してテストすることは何もありませんし、私はパフォーマンスのチェックこの立場にないんだけど怖いように私がチェックしていません。

あなたのコードはアーカイブに存在しないことに基づいてアーカイブテーブルに挿入する行を選択しているようです。したがって、適切なROWNUM値によって制限されたSELECTに基づくINSERTを使用するだけです。いったんコミットすると、ループの次回には、コミットしたばかりのアーカイブ済みの行を取得しようとしません。

私は、これがより簡単であるという利点を持ってインサートを大きくするよりも速くなければ、すばやくすべきだと思います - Occams Razorとそのすべて。

DECLARE 
    l_commit_count NUMBER := 10000; 
    l_rows_copied NUMBER := 0; 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Started at '||TO_DATE(SYSDATE, 'DD_MON_YYY HH24:MI:SS'); 
    LOOP 
     INSERT /*+APPEND */ 
     INTO c_arc_act_plus_triggers1 
     SELECT /*+ PARALLEL */ apt.* 
      FROM act_plus_triggers1 apt 
      WHERE NOT EXISTS 
        (SELECT 1 
         FROM act_plus_triggers_copy1 aptc 
         WHERE aptc.surr_id = apt.surr_id) 
      AND apt.status IN ('EXT', 'EXP') 
      AND rownum < l_commit_count; 

     COMMIT;   
     l_rows := l_rows + SQL%ROWCOUNT; 
     EXIT WHEN SQL%ROWCOUNT < 1; 
    END LOOP   
    DBMS_OUTPUT.PUT_LINE('Finished at '||TO_DATE(SYSDATE, 'DD_MON_YYY HH24:MI:SS'); 
    DBMS_OUTPUT.PUT_LINE(TO_CHAR(l_rows)||' rows copied to the archive table'); 
END; 
+0

私は上記を試し、あなたに戻ってきます –

関連する問題