少し異なるアプローチは、トリガーを有効にしたまま、when
を追加することで、トリガーの影響を(完全に削除しない場合でも)減らすことです。 次のような句:
create or replace trigger ...
...
for each row
when (sys_context('userenv', 'client_info') is null
or sys_context('userenv', 'client_info') != 'BATCH')
declare
...
begin
...
end;
/
次に、手順でに呼び出しを追加します。開始 「トリガーを無効にする」ステップとして:
dbms_application_info.set_client_info('BATCH');
セッションが存続して再利用された場合に備えて、最後にもう一度クリアします(したがって、例外ハンドラーでもこれを実行することをお勧めします):
dbms_application_info.set_client_info(null);
モジュール、アクション、または組み合わせを使用することもできます。その設定が設定されている間、トリガーは評価されますが起動しないため、内部で発生することはすべてスキップされます。ドキュメント 入れてください。
他のユーザー/アプリケーションが同じ呼び出しを行うのを実際に止めるものは何もないので、これは絶対確実ではありませんが、より説明的な文字列や設定の組み合わせを選択する場合は、慎重に行う必要があります-そして私はあなたがほとんどだと思います悪役ではなく事故を心配している。
物事を少し遅くするだけの無意味なトリガーを使用したクイックスピードテスト。
create table t42 (id number);
-- no trigger
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.050
create or replace trigger tr42 before insert on t42 for each row
declare
dt date;
begin
select sysdate into dt from dual;
end;
/
-- plain trigger
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.466
create or replace trigger tr42 before insert on t42 for each row
when (sys_context('userenv', 'client_info') is null
or sys_context('userenv', 'client_info') != 'BATCH')
declare
dt date;
begin
select sysdate into dt from dual;
end;
/
-- userenv trigger, not set
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.460
- userenv trigger, set to BATCH
exec dbms_application_info.set_client_info('BATCH');
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.040
exec dbms_application_info.set_client_info(null);
リモート呼び出しを行うこととは少し異なりますが、数回実行しました。プレーントリガーを使用した実行は、BATCHを設定せずに制約付きトリガーを使用した実行と非常に似ており、どちらもトリガーなしまたはトリガーを使用した実行よりもはるかに低速です。 BATCHが設定された制約付きトリガー。私のテストでは、桁違いの違いがあります。