• 締切済み

トリガの使い方

 すみません、DB仕事で少ししただけです。  トリガつかったことありませんが、今回事情があって、トリガを使おうと思っています。  なお、今回は自分でプログラムするのではなく、こういう方針でやってほしいとお願いする立場になります。(すでに運用しているシステムの修正)  テーブルAとテーブルBがあって、テーブル構成は同じです。本来はテーブルAで準備して、カラム全部がそろったところで、テーブルBに移す仕様になっていたのですが、わかっていない人たちが多くて、テーブルBに直接書いているプログラムが多く出てしまいました。おかげで、カラム全部そろっていないのに、一部だけ書くから、そろっていない状態で動き出す後段のプログラムまででてきて、大変な状態になってしまいました。  プログラムの箇所は多くて、とてもそれらを直す場所を探し出すことはできないといっています。  それで、 1)テーブルBにいきなり書いているやつ(プロセス名で特定のも以外はすべて対象、もしくは、特定プロセスにご作法を設けて、そのご作法以外で更新してきた場合でトリガを仕掛けたいです。できなければトリガの中で判定。 2)悪さをしているやつからの書き込みだった場合に、そのテーブルBへの書き込みを無効にして、その代わりにテーブルAに書き込みをさせる  なんてことはできるのでしょうか?また、どうやってやるのか、概略も知りたいです。  どうぞよろしくお願いいたします。  なお、データベースはDB2なのですが、そうでなくても概念としてOKなのかどうかを確認したく、ほかのデータベースでもいいので、お教えください。

みんなの回答

  • AS400
  • ベストアンサー率69% (9/13)
回答No.2

> Inserted of trigger ではなくて、InsertBefore みたい > なものはないのでしょうか?そうしないと、すでに更新さ > れたあとにトリガがかかるような気がするのですが。 Before trigger機能は存在しますが、before triggerでfireした処理を行ったあとで、表は更新されるので、今回のケースには適さないと思います。 > InsertBeforeの中で、そのInsertを無効にするなんて > ことはできないのでしょうか? 繰り返しになりますが、出来ません。 > 本当にこれで表B(というか、表Cのことかな)は更新 > されないのですか?そこが気になりました。 はい。普通のBefore/After Triggerは表への操作自体(INSERTとか)は必ず実行されますが、Instead of triggerは、表に対しての操作は一切反映されません。 (DB2の場合はInstead of triggerをViewにしか設定できません)

watjapan
質問者

お礼

AS400さま ありがとうございました。 私がインターネットで調べたところ、 SETコマンドで、値を書き換える(元の値に書き換える)ことによって、無効にするのと、同じ効果が得られると解釈しました。 The triggered action may refer to the values in the set of affected rows. This is supported through the use of transition variables. Transition variables use the names of the columns in the subject table qualified by a specified name that identifies whether the reference is to the old value (prior to the update) or the new value (after the update). The new value can also be changed using the SET transition-variable statement in before update or insert triggers. Another means of referring to the values in the set of affected rows is using transition tables. Transition tables also use the names of the columns of the subject table but have a name specified that allows the complete set of affected rows to be treated as a table. Transition tables can only be used in after triggers; and separate transition tables can be defined for old and new values. ただ、現実の話として、速度なども問題になると思われ、保留しています。

  • AS400
  • ベストアンサー率69% (9/13)
回答No.1

難しそうですね。。 要件をちゃんと理解していないので、変な回答かもしれませんが、ご参考まで。 表Bに対してUPDATE/INSERTがあった際に、同じデータを表AにUPDATE/INSERTするようなトリガーは作成可能です。この場合は表A,BともにデータがUPDATE/INSERTされます また、もし表Bに対する更新があっても、表Bにはデータは残さず、表Aのデータを更新したいのでしたら、かなり面倒ですが、 1)表Bを表Cという名前に変更する 2)Bという名前で、表Cを参照するVIEWを作成する 3)そのVIEW Bにinstead of triggerを付ける という方法でBに対する更新はすべてトリガーで捕捉できます。が、この方法にしてもそのトリガー内でwatjapanさんが希望されているような判別処理が組めるかどうかは分からないです。

watjapan
質問者

補足

ありがとうございます。Inserted of trigger ではなくて、InsertBefore みたいなものはないのでしょうか?そうしないと、すでに更新されたあとにトリガがかかるような気がするのですが。一般的なことがわかっておらず、申し訳ありません。InsertBeforeの中で、そのInsertを無効にするなんてことはできないのでしょうか?判別処理に関しては、実は何とかなると思っています。  ところで、AS400さまが、「表Bにはデータは残さず、表Aのデータを更新したいのでしたら、かなり面倒ですが、・・・」のところですが、本当にこれで表B(というか、表Cのことかな)は更新されないのですか?そこが気になりました。

関連するQ&A