9

eventというテーブルが1つ あり、同じ列とeventを持つ定義を持つ別のグローバル一時テーブルtmp_eventを作成しました。これを使用して、イベントのレコードをtmp_eventに挿入することは可能ですか?

DECLARE
   v_record event%rowtype;
BEGIN 
   Insert into tmp_event values v_record;
END;

イベントテーブルの列が多すぎます。すべての列を一覧表示したくないので、これを試してみます。

言及するのを忘れてください:私はこれをトリガーで使用します、このv_recordはEVENTテーブルに挿入した後のオブジェクト:newになることができますか?

4

3 に答える 3

21

1行挿入するには-

DECLARE
   v_record event%rowtype;
BEGIN 
   SELECT * INTO v_record from event where rownum=1; --or whatever where clause
   Insert into tmp_event values v_record;
END;

eventまたは、 -からすべての行を挿入するためのより複雑なバージョン

DECLARE
  TYPE t_bulk_collect_test_tab IS TABLE OF event%ROWTYPE;

  l_tab t_bulk_collect_test_tab;

  CURSOR c_data IS
    SELECT *
    FROM event;
BEGIN
  OPEN c_data;
  LOOP
    FETCH c_data
    BULK COLLECT INTO l_tab LIMIT 10000;
    EXIT WHEN l_tab.count = 0;

    -- Process contents of collection here.
    Insert into tmp_event values v_record;
  END LOOP;
  CLOSE c_data;
END;
/

トリガーでは、はい、それは可能ですが、それは鶏が先か卵が先かと同じです。のすべてのフィールドを次のような列値で初期化する必要がありrowtypeます:new-

v_record.col1 := :new.col1;
v_record.col2 := :new.col2;
v_record.col3 := :new.col3;
....

明らかに、上記のPLSQLの例は、変更トリガーエラーをスローするため、トリガーで使用できません。また、上記で説明したように、各列に個別にアクセスする以外に、トリガーの行全体を取得する方法はありません。したがって、これらすべてを実行する場合は、それ自体を直接使用:new.colしないINSERT into temp_eventと、多くの作業を節約できます。


また、すべての列について言及するのは大変な作業だと言うので(Oracle 11gR2INSERTでは)、ステートメントを生成して動的に実行することで、これをすばやく行う方法を示します(ただし、パフォーマンスはテストされていません)。

CREATE OR REPLACE TRIGGER event_air --air stands for "after insert of row"
AFTER INSERT ON EVENT
FOR EACH ROW
   L_query varchar2(2000);   --size it appropriately
BEGIN

   SELECT 'INSERT INTO tmp_event VALUES ('|| listagg (':new.'||column_name, ',') 
                                           WITHIN GROUP (ORDER BY column_name) ||')' 
     INTO l_query
     FROM all_tab_columns
    WHERE table_name='EVENT';

   EXECUTE IMMEDIATE l_query;

EXCEPTION
    WHEN OTHERS THEN
        --Meaningful exception handling here
END;
于 2012-12-13T19:30:06.067 に答える