• ベストアンサー

トリガーの設定方法

いま、まったく同じ型のTABLE1,TABLE2の2つのテーブルがあり、 TABLE1にInsertやUpdateがかかると、自動的にTABLE2の方にも 同じようなInsertやUpdateが走る仕組みを作りたいと考えています。 TABLE1にトリガーを設定すれば可能ということは判ったのですが、 どのようにトリガーを記述すればわからず、困っています。 特に、「AS」以降の記述方法が判りません。 TABLE1にかかったクエリを同じようにTABLE2にもかかるように するにはどのように記述すればいいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

トリガを利用すると、そのトリガがかかったテーブルに対する「クエリの結果」を知ることはできますが、「クエリの内容」まで知ることはできません。 例えば「クエリの結果」がテーブルの最初の1行になるようなクエリを考えてください。そのような結果を得られるクエリは何通りも考えられるわけですが、そのうちどのクエリを実行してトリガが実行されたのかを判別することはできません。 ですので、トリガを使用して、全く同じクエリを他のテーブルに対して実行することはできません。 しかし「クエリの結果」は分かりますので、例えば「主キーを共有しており一方への追加・削除は他方へも反映したい」というような場合には、クエリの結果を使用して他のテーブルに対して処理を行うことはできます。(クエリの結果は、トリガ内だけで使用できるinsertedとdeletedという特殊なテーブルを使用します。)

その他の回答 (1)

  • 9arabi
  • ベストアンサー率32% (140/433)
回答No.2

ちょっと自信がないのですが、リレーションはることでできませんでしたっけ? トリガは、No1さんのいわれるとおり、insertedとdeletedという一時テーブルを使うのですが、 updateが走ったとき、deleted+insertedを使います。 なので、 FOR INSERTのときには insert into TABLE2 select * from inserted とか FOR DELETEのときには detete TABLE2 where 主キー = (select 主キー from deleted) とか、そんなかんじで使います。 でも、あんまり頻繁に更新がかかるようなら、とても重くなったはずなので、あんまりオススメしません。 プログラム側で、同じように更新をかけに行くようにするか、リレーション(自信ないですが)かなと思います その線で一度みてみてください

関連するQ&A

  • ORACLEのトリガーについて勉強しているのですが現在詰っています。

    ORACLEのトリガーについて勉強しているのですが現在詰っています。 トリガーの内容ですが、table1のレコードがUPDATEかINSERTかDELETEが 実行された時にtable2にそのレコードすべてをINSERTしたいのですが CREATE OR REPLACE TRIGGER test_trg After INSERT or UPDATE or DELETE on table1 for each row  BEGIN   if inserting then    insert into (?);   elsif updating then    insert into (?);   else    insert into (?);   end if;  END; tableを使ってログを残せるようにするためこのトリガーを作ろうとしています。 この様な感じになると思っているのですが、(?)の部分をどう書けばいいのか がよくわかりません。どうしても解らないので教えていただければ幸いです。 何卒よろしくお願いします。

  • プロシージャとトリガー

    Aというテーブルのaカラムが更新されれば、Bテーブルの列の中でAテーブルの列id含む列(複数)のbカラムをFalseからTrueに変更されるような、トリガー と プロシージャを作りたいのです。 考えていたのは、プロシージャは、 CREATE FUNCTION update_edit_b() RETURNS OPAQUE AS ' BEGIN (複数列指定?) NEW.b := 't'; RETURN NEW; END; ' LANGUAGE 'plpgsql'; プロシージャで、Bテーブルの複数列を指定するにはどうしたら良いでしょうか? トリガーは CREATE TRIGGER trgger_a AFTER UPDATE OF a ON Table_a FOR EACH STATEMENT EXECUTE PROCEDURE update_edit_b ; こんな感じでしょうか?

  • トリガーについて

    このジャンルでお願いします。 次のようなテーブルで DROP TABLE IF EXISTS item; CREATE TABLE IF NOT EXISTS item ( id int(11) NOT NULL AUTO_INCREMENT, parent_id INT, name varchar(32) NOT NULL, level int NOT NULL, FOREIGN KEY (parent_id) REFERENCES item(id) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO item (parent_id, name) VALUES (null, 'item1'); INSERT INTO item (parent_id, name) VALUES (1, 'item2'); INSERT INTO item (parent_id, name) VALUES (2, 'item3'); INSERT INTO item (parent_id, name) VALUES (3, 'item4'); INSERT INTO item (parent_id, name) VALUES (2, 'item5'); INSERT INTO item (parent_id, name) VALUES (null, 'item6'); INSERT INTO item (parent_id, name) VALUES (6, 'item7'); INSERT INTO item (parent_id, name) VALUES (null, 'item8'); DROP PROCEDURE IF EXISTS UPDATE_LEVEL; DELIMITER // CREATE PROCEDURE UPDATE_LEVEL() BEGIN DECLARE CNT INT; DECLARE LVL INT; SET LVL=1; UPDATE item SET level=0; UPDATE item SET level=LVL WHERE parent_id IS NULL; SELECT COUNT(*) INTO CNT FROM item WHERE level=LVL; WHILE CNT>0 DO UPDATE item INNER JOIN (SELECT id FROM item WHERE level=LVL) as temp ON parent_id=temp.id SET item.level=LVL+1; SET LVL=LVL+1; SELECT COUNT(*) INTO CNT FROM item WHERE level=LVL; END WHILE; END // DELIMITER ; DROP TRIGGER IF EXISTS TRG_INSERT_ITEM; DELIMITER // CREATE TRIGGER TRG_INSERT_ITEM AFTER INSERT ON item FOR EACH ROW BEGIN CALL UPDATE_LEVEL(); END; // DELIMITER ; itemテーブルにinsertした場合にトリガーでUPDATE_LEVEL()を実行するようにしているのですが、 実際に挿入すると、 >Can't update table 'item' in stored function/trigger because it is already used by statment which invoked this stored function/trigger . このようなエラーが出てしまいます・・・ UPDATE_LEVEL()にinsertらしき記述はないと思うのですが、 これはなぜこのようなエラーが出るのでしょうか?

    • ベストアンサー
    • MySQL
  • SQLServerトリガー(データ追加時)

    Microsoft SQL SERVER 2005でデータ更新/追加時に起動するトリガーを 作成したいのですが記述方法がわかりません。 テーブル:TBL_SHOHIN SHOHIN_NAME NVARCHAR(50) /* 商品名 */ SAKUSEI_DATE datetime /* 作成日付 */ KOSHIN_DATE datetime /* 更新日付 */ このTBL_SHOHINテーブルに追加があった時は、作成日付(SAKUSEI_DATE)にシステム日付をセット このTBL_SHOHINテーブルに更新があった時は、更新日付(KOSHIN_DATE)にシステム日付をセット 更新時は下記の記述でうまくいったのですが、追加時をどう記述すればいいの でしょうか? create TRIGGER trgSHOHIN ON TBL_SHOHIN FOR INSERT, UPDATE AS BEGIN UPDATE TBL_SHOHIN SET KOSHIN_DATE = GETDATE() END RETURN

  • 一時表 を表単位で

    お世話になっております。 Oracle10gで テーブル単位でTemporary Tableが出来ないか 試行錯誤しております。 要件として、Webアプリケーションで100万件のデータをSelectします。 その際、全データを取得するには、遅すぎるので、分割して取得しています。 現在では、C#で、サーバ側で取得Temporary Table Insertして、そのデータを参照するようにしているのですが、 Insertが遅いのと、C#に一度持ってきていますので、メモリが不安な状態です。 これを、create global temporary table CRE_TABLE_NAME as select * from TABLE_NAME にして、CRE_TABLE_NAMEを参照したいのですが、dropタイミングがつかめませんでした。 そこで、このテーブルが自動的にdropしたいのですが、何か良い案はありませんでしょうか? 思いついたのが、temporary tableにテーブル情報を保持して、sessionが切れた、時点で消えるのを利用して、テーブルdropのトリガーを記載しようと思ったのですが、そのトリガーを思いつきませんでした。 どなたか、代替案または、実装したことがある方、よろしくお願いします。

  • OracleのTrigger(トリガー)について

    いつもご親切にありがとうございます。 Oracleのトリガーについて教えてください。 テーブルA ----------------- 日付 date型 品名 char(15) 営業所 cahr(5) フラグ char(1) データをINSERTする際に、下記のように変更したいです。 (1)日付が2月且つ、営業所が00001の場合は99999に変更、 (2)日付が2月且つ、品名の後ろ5桁が00001の場合後ろ5桁だけを99999に変更 下記のようにトリガーを作成しているんですけど、 (2)をどのように入れたらよいでしょうか? CREATE OR REPLACE TRIGGER TRG_テーブルA BEFORE INSERT ON テーブルA REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW BEGIN IF ( to_char(:NEW.日付,'YYYYMM') = '201502' ) AND ( :NEW.営業所 = '00001' ) THEN :NEW.営業所 := '99999'; END IF; END; / よろしくお願いします。

  • トリガーにてビューを作成しようとすると・・

    WindowsXPのOracle9i環境です。 以下のようなトリガーを作成しました。 create or replace trigger kan_trg after update or insert on t_kan declare begin execute immediate 'create or replace view V_test as select ・・ from t_kan with read only'; end; / その後、試しに「insert into t_kan ・・・」 と実行してみましたが、「ORA-04092:トリガーはCOMMITできません」が発生します。 色々調べましたがトリガーの中にCOMMIT文を入れることはできないようです。どのようにすれば解決するか、ご教示いただけませんでしょうか? 宜しくお願い致します。

  • PL/SQLトリガー機能

    PL/SQLでトリガーを使って下記処理をしたいのですが教えてください。 処理内容 a在庫数テーブルの在庫数がUPDATE(After UPDATE)するたびに b在庫数テーブルにa在庫数の店CD(KEY1)と商品CD(KEY2)と取引日と当日売上日と在庫数を追加(INSERT) この時、 b在庫数テーブルのkey店CD(KEY1)と商品CD(KEY2)と取引日(KEY3)が同じ場合、在庫数のみを更新(UPDATE)する。 上記の事柄のトリガー機能・処理分を教えてください。 よろしくお願いします。

  • Oracleのトリガーについて

    Oracleのトリガーについて質問です。 旧システムから新システムへデータ移行を行おうとしているのですが、 新システムではNEWテーブル(仮名)が新規で追加されています。 データ移行の方法として、旧システムのダンプファイルをエクスポートし、 新ステムにユーザを再作成後インポートしました。 その後、あらかじめ新システムでNEWテーブルのみテーブル指定のエク スポートを行っていたダンプファイルより、追加でインポートを行いました。 これでデータ移行完了と思っていたのですが、NEWテーブルのデータはトリガー により生成されるらしいのですが、どのタイミングで生成されるのでしょうか? データ移行完了時はデータ0件です。 NEWテーブルをインポートする順番が逆なのでしょうか? それともインポートではトリガーは起動しないのでしょうか? または、トリガーの仕組みが消えている(?)のでしょうか? (納入先に行かないと確認できない状態なので実際のデータベースが確認できません…) Oracleはあまり詳しくないため、わかりづらい質問かもしれませんが よろしくおねがいします。 【環境】 Oracle11g R2 Windows2008Server

  • 効率のよい方法があったらお教え下さい

    下記の仕様を元にAccessでプログラムを組もうと考えています。 「プログラムをするにあたっての方法」のように組もうと考えているのですが、効率が悪いように何となく感じています。 もし、こういった方法でプログラムしたらという方法がありましたらお教え下さい。 ------------------------------------------------------- 仕様 ------------------------------------------------------- TABLE1とTABLE2があります。 TABLE1は履歴蓄積テーブル。 TABLE2は新規インサート用テーブルです。 両テーブルともにIDフィールドがあります。 TABLE1に取得IDが無ければ、TABLE2にインサート。 TABLE1に取得IDが存在すれば、TABLE2にインサートをおこなわない。 取得IDはテキストファイルにあります。 ------------------------------------------------------- プログラムをするにあたっての方法 ------------------------------------------------------- TABLE1のレコードセットを取得 取得IDをキーにTABLE1のレコードセット・IDフィールドを検索 取得IDがレコードセットに無ければ Insert文でTABLE2に挿入 取得IDがレコードセットに有れば Insertをおこなわない テキストのIDがEOFになるまで繰り返し 終わり