[pgsql-jp: 27822] Re: PL/pgSQL のトリガプロシージャで SQL ログをとる方法

Jun Kitamura kitamura @ zoozee.jp
2002年 10月 29日 (火) 11:08:17 JST


北村@zoozee です。

> 複数のテーブルに対しPL/pgSQLで作成したトリガを組み込み、
> ログテーブルに、
> 
> 	カラム1		変更日付(実際はDefault NOW()定義)
> 	カラム2		テーブル名
> 	カラム3		SQL文
> 
> といったような感じでログを書き出したく思っております。
> 
> そこで煮詰まっているのが、カラム3のSQL文で、PL/pgSQLの定義済み
> 変数のTG_OPだと、トリガを発行した操作を示す'INSERT'、'UPDATE'、'DELETE'
> という各文字列は定義されているようですが、実際に欲しているトリガを発行した
> 操作の「SQL文」は定義されていないようです。
(snip)
> ・・・・ながながと汚い日本語を連ねてしまいましたが、良い方法をご教授
> 	願います。

ログに吐き出すことができます。
http://www.postgresql.jp/document/pg721doc/admin/runtime-config.html
セクション 3.4.2 ログとデバッグ 参照。この場合、SELECT など
のクエリも記録されちゃいますが。

どうしても、psql などから SELECT 使ってログを閲覧したい・・
・というのであれば、クライアント側プログラムでクエリを実行し
た後(か前)にログテーブルにインサートさせるのが良いかと。
もちろん、1つの処理で 2回クエリを発行するので数によってはパ
フォーマンスに影響を与えます。
それが気になるのであれば、今回の場合は INSERT、UPDATE、
DELETE のみなので、それらを実行しログテーブルにクエリを記録
する関数を使っても実現できます。下記の例ではテーブル名が記録
されませんが、クエリの中にテーブル名は指定されているので、テー
ブル名を取り出す関数を別途作るか、ログテーブルを SELECT する
時に条件式(WHERE句)の中で指定すれば問題ないはずです。
トリガを使う方法と同様に、クエリが失敗した時、ログテーブルに
記録されません。

これは 1つの案であり、他にいくらでも方法はあります。

ではでは。

-- 適当なテーブル
create table t1(a int2);

-- ログテーブル
create table tLog(
 LogDateTime datetime default now(),
 TableName text,
 QueryText text
);

-- ログ記録付き Execute
create function fExec(text) returns bool as 
'
 BEGIN
  -- ログ
  insert into tLog(QueryText) values ($1);
  -- 実行
  EXECUTE $1;
  -- 結果
  return true;
 END;
'
language 'plpgsql';

select fExec('insert into t1(a) values (1)');

drop table t1;
drop table tLog;
drop function fExec(text);





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