-2

解決しなければならない新しい質問があります!タイプとしてテーブルを作成しました

TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
rbkTable        ebRBKTable;

次に、次のステートメントを使用してテーブルにデータを挿入します

rbkTable(InsertTable).BDADDUSERID             := 'FT_RBK_TDCC';

最後に次のステートメントを挿入します

FORALL i IN 1..InsertTable - 1
INSERT INTO EBTDCCRBK VALUES rbaTable(i);

すべてのタイプを一度に挿入せずに挿入する方法はありますか?count(i)

ありがとう!

4

1 に答える 1

1

forallステートメント自体はループではありません。

配列のすべての要素を一度にSQLエンジンに送信します。これにより、SQLは、PL / SQLエンジンに戻ってデータを取得しなくても、行を挿入できます。

つまりFORALL、通常のFORループで発生するコンテキスト切り替えを削除します。

これは簡単なトレースで示すことができます。検討:

SQL> alter session set sql_trace=true;

Session altered.

SQL> declare
  2    TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
  3    rbkTable        ebRBKTable;
  4  begin
  5
  6    for idx in 1..100000
  7    loop
  8      rbkTable(idx).BDADDUSERID := dbms_random.string('a', 10);
  9    end loop;
 10
 11    forall idx in 1..rbkTable.count
 12    insert into EBTDCCRBK values rbkTable(idx);
 13    commit;
 14
 15  end;
 16  /

SQLトレースでは、次のように表示されます。

INSERT INTO EBTDCCRBK
VALUES
 (:B1 )


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.07       0.07          1        724       3066      100000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.07       0.07          1        724       3066      100000

vs regluarループ:

SQL> alter session set sql_trace=true;

Session altered.

SQL> declare
  2    TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
  3    rbkTable        ebRBKTable;
  4  begin
  5
  6    for idx in 1..100000
  7    loop
  8      rbkTable(idx).BDADDUSERID := dbms_random.string('a', 10);
  9    end loop;
 10
 11    for idx in 1..rbkTable.count
 12    loop
 13      insert into EBTDCCRBK values rbkTable(idx);
 14    end loop;
 15    commit;
 16
 17  end;
 18  /

PL/SQL procedure successfully completed.

SQL> alter session set sql_trace=false;

トレースファイルは次のことを示しています。

INSERT INTO EBTDCCRBK
VALUES
 (:B1 )


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute 100000      3.33       3.24          1        689     104216      100000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total   100001      3.33       3.24          1        689     104216      100000

バージョンのトレースファイルはFORALL1回しか実行されなかったことに注意してください。つまり、SQLエンジンが1回のヒットで作業を実行しました。バリアントではFOR LOOP、SQLエンジンは100kの実行を行い、同じジョブを実行するためにより多くのCPUを使用しました(多くの単一操作を実行する必要があり、セッションは挿入された行ごとにpl / sql->sqlからコンテキストを切り替えていたため) 。

于 2013-03-26T11:25:09.310 に答える