[pgsql-jp: 30474] Re: トリガを作れない

Jun Kitamura kitamura @ zoozee.jp
2003年 7月 15日 (火) 11:04:06 JST


北村です。

> g_takiです。
(略)
> 手元にはPostgresの本が1冊も無いことに気づき、
> これから本屋にも行ってこようと思います。
> トリガやファンクションを解説している本があればよいのですが・・・

私は、石井達夫<t-ishii @ sra.co.jp>さんの PostgreSQL完全攻略ガ
イド(改訂版)(技術評論社)を見て、勉強してました。
初版が PDF で公開されています。改訂版では3章にトリガの説明が
あります。
http://www.sra.co.jp/people/t-ishii/PostgreSQL/postbook-pdf/

ただ、当時は戻り値が OPAQUE という型だったのですが、今は 
TRIGGER 型になっています。今でも OPAQUE は使えるようですが。
そういう意味では、微妙に変わってきている箇所が多いので、購入
するのであれば、改訂 第3版(しばらく待てば新しいの出るかもw)
の購入をおすすめします。

> やりたいことは、
> 1:a,b,c,d,,,,といくつかのTableがある。
> 2:update_infoというテーブルがあり、以下のように構造で、
> 
> 	table_name(TEXT型)	moddate(TIMESTAMP型)
> 	a			2003/07/11 **:**:** ****
> 	b			2003/07/12 **:**:** ****
> 	c			2003/07/13 **:**:** ****
> 
> 3:Table a が更新されたら、
>   update update_info set moddate = now() WHERE table_name = 'a';
>   を行いたい
>   Table b が更新されたら、
>   上記SQLは update 中略 WHERE table_name = 'b';
> 
> といった具合です。

この場合、1つのトリガ用関数を、各テーブルにトリガとして実装
したほうが良さげです。plpgsql で使えるトリガ用の特殊変数とい
うのがあり、テーブル名も取得できます。g_taki さんもご覧になっ
た、
http://www.postgresql.jp/document/pg732doc/programmer/plpgsql-trigger.html
に出てます。

create or replace function fTimeStamp() returns TRIGGER as
'
 BEGIN
  IF (select count(*) = 1 from update_info
       where table_name = TG_RELNAME) THEN
   update update_info set moddate = now()
    -- , updatedby = current_user
    -- (更新ユーザーは記録しなくて良いの?)
    where table_name = TG_RELNAME
    ;
  ELSE
   -- (初めての時は追加しなくて良いの?)
   insert into update_info(
    table_name,
    moddate
    -- ,updatedby
   ) values (
    PG_RELNAME,
    now()
    -- , current_user
   );
  END IF;
  return NEW;
 END;
'
language 'plpgsql'
SECURITY INVOKER;

というトリガ関数を、記録が必要な全てのテーブルにトリガとして
実装します。
-- でコメントアウトされているところは、更新ユーザーの記録が
必要な場合、カラム updatedby(text) を update_info に追加して
ください。また、対象となるテーブル名がなかった場合、
update_info に行を追加しなくても良いのですか? それとも手動
で INSERT ?。そのへんはそちらのポリシーの範疇ですね。失礼し
ました。

でわ。





pgsql-jp メーリングリストの案内