web-dev-qa-db-ja.com

Oracle-例外をスローせずに「挿入前」トリガー内で中止する

これは多くの理由で行うにはひどいことですが、Get Things Doneモードで、レコードをテーブルに書き込む、変更できないソフトウェアがあります。これらのレコードの一部は、ビジネス上の理由から、このテーブルには入れません。エラーをスローすることなく、これらの行のいずれかを「打ち切る」トリガーを作成できると考えていました(アプリケーションがフロントエンドで失敗しないように、アプリケーションがそれを実行したと考えてほしい)。私はこのアプリケーションに精通しており、醜い副作用を引き起こさないことがわかっています。必要な動作をするように変更することはできません。

それで、これは可能ですか、それができない場合は、それについて別の方法で何をすべきでしょうか?不要なレコードのテーブルを定期的にクリーンアップするジョブのようなものを考えましたが、これらのレコードが最初にそこに決してないようにしたいので、一度にある程度の「汚れ」はありませんテーブル。

3

テーブルのトリガーがINSERT操作の完了を防ぐ唯一の方法は、エラーをスローすることです。

あなたが述べたように、それは巨大なハックですが、

  • テーブルの名前を変更する
  • 元のテーブルと同じ名前のビューを作成します
  • 行を永続化する場合は、テーブルでINSERTのみを実行するビューにinstead ofトリガーを作成します。そうでなければ、トリガーは何もしません。

これは、アプリケーションがテーブルにMERGEを実行していない限り機能します。もちろん、これはハックのハックであるため、クリーンなコードで賞を獲得することはできません。

9
Justin Cave

Virtual Private Database を使用して、これらの行をクリーンアップする前にユーザーから非表示にすることもできます。

0
sjk

これを実現する最も簡単で簡単な方法は、一時テーブルとステートメントトリガーを使用することです。

1)レコードの主キーを使用して一時テーブルを作成します

create global temporary table TMP_ID_NUMBER
(
  id NUMBER(9) not null
)
on commit delete rows;

2)行トリガー

不要なすべてのレコードを一時テーブルに挿入します...

create or replace trigger MY_TEST_REMOVE_IDS_TR
  before insert
  on MY_TEST 
  for each row
begin
  if :new.Id in (100, 101, 501) then
    insert into tmp_id_number
      (id)
    values
      (:new.Id);
  end if;
end MY_TEST_REMOVE_IDS_TR;

3)ステートメントトリガー

そして、それらをafterステートメントトリガーのベーステーブルから再び削除します...

create or replace trigger MY_TEST_REMOVE_IDS_STAT_TR
  after insert
  on MY_TEST 
begin
  delete MY_TEST d
   where d.Id in (select t.Id
                  from Tmp_Id_Number t);
end MY_TEST_REMOVE_IDS_STAT_TR;