2

多くの関数と関係を使用するさまざまなテーブルから、INSERT を SELECT として使用しています。選択すると、一度に約 10 行が返されます。

クエリは次のようになります

INSERT INTO EIM_TABLE(certain columns)
select a,b,...,fn(x,y,)

ここで、 によって返された値を収集し、fn(x,y)各値を 1 つの変数に連結し、これに基づいてさらに処理を実行する必要があります。

パフォーマンスは非常に重要な基準であるため、不要なオーバーヘッドは避けたいと考えています。

4

1 に答える 1

1

残念ながら、INSERTステートメントの return into句は、 values句でのみ使用できるため、これはそれほどきれいではありません。

挿入しているデータを 2 回選択せずに再利用したい場合は、再利用できる場所に配置する必要があります。これは、GLOBAL TEMPORARY TABLE (GTT)またはユーザー定義型のいずれかです。

個人的には、タイプの方が柔軟性があると思うので、タイプの方が好きです。何をしたいかは、その後にどのような処理を行う必要があるかによって異なります。結果に対して SQL を実行する必要がある場合は、GTT の方が適しています。

ユーザー定義型で何かをしたい場合は、それをBULK COLLECTと組み合わせてください。次のようになります。

ポイントは、作成する SELECT ステートメントであるカーソルを宣言することです。次に、その SELECT ステートメントの値を保持できる型を宣言します。次に、すべてのデータをその型に収集します。それが完了したら、どこにでも INSERT して、必要な他の操作を実行できます。一般に、できることはすべて PL/SQL ではなく SQL で行う方がよいでしょう。PL/SQL を使用した方が速いという確信がない限り、これ以上の処理は行わないでください。

declare

   cursor c_stuff is
    select a, b, ..., fn(x, y) as fn
      from somewhere;

   type t__stuff is table of c_stuff%rowtype index by binary_integer;
   t_stuff t__stuff;

   l_new_stuff varchar2(100);

begin

   open c_stuff;
   fetch c_stuff bulk collect into t_stuff;
   close t_stuff;

   forall i in t_stuff.first .. t_stuff.last
      insert into somewhere_else values (t_stuff(i));

   for i in t_stuff.first .. t_stuff.last loop
      l_new_stuff := l_new_stuff || t_stuff(i).fn;
   end loop;

   ...

GTT ルートを下ると、少し楽に見えます。SELECT ステートメントによって返されるものと同じデータ型を持つテーブルを作成します。

create global temporary table gtt_stuff (
     a number
   , b ...
   , fn ... )
  on commit delete rows;

次に、このテーブルに挿入します。テーブル内のデータを操作して、通常のテーブルと同じように利用できます。DELETE ROWS を使用した場合はトランザクションが終了するまで、PRESERVE ROWS を指定した場合はセッションが終了するまで、データは存続します。

の結果を連結していると言うfn()ので、おそらく次のようになります。

select listagg(fn) within group (order by 1)
  into l_new_stuff
  from gtt_stuff;

また、GTTとテーブルに同時にINSERT できるように、マルチテーブル INSERT を使用できるコメントの David Aldridge の (素晴らしい) 提案にも注意してください。

insert all
   into gtt_stuff values (a, ..., fn) -- only necessary columns
   into somewhere_else values (a, b, ..., fn)
select a, b, ..., fn
  from somewhere
于 2013-08-31T11:08:03.930 に答える