sql >> データベース >  >> RDS >> Oracle

トリガーを無効にし、トリガーを再度有効にしますが、その間はテーブルの変更を避けてください

    少し異なるアプローチは、トリガーを有効にしたまま、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が設定された制約付きトリガー。私のテストでは、桁違いの違いがあります。




    1. sqlldr値を置き換える方法

    2. DockerとFlaskでPostgreSQLデータベースを使用すると、どのように機能しますか?

    3. 連続スクロール。 AJAX、PHP、JAVASCRIPT、MYSQL

    4. get_lockから現在のすべてのロックを表示する