[pgsql-jp: 31491] TRIGGERの中で使用する「now」について
bxcel
bxcel @ prophet.jp
2003年 11月 18日 (火) 17:46:39 JST
松本と申します。
TRIGGERの中で使用する「now」について教えてください。
あるテーブルの更新ログテーブルを作成し、TRIGGERを使用
して更新や削除の時に前のデータを保存するようにしました。
この時に更新や削除したユーザと時間を記録するようにしました。
この更新や削除した時間に「now」を使用して更新や削除を
実行した時間が入る事を期待していたのですが、複数回実行
すると2回目以降も1回目と同じ時間が入ってしまいます。
どうも同じコネクションにて複数回更新及び削除すると、
最初に取得された「now」の値が引き継がれているように
見えるのですが、何か設定を間違えているのでしょうか。
RedHat Linux 7.3 で Postgres 7.3.3 と Postgres 7.3.4で
試してみましたが現象は同じでした。
以下は詳細になります。
--ここから-----------------------------------------------------
--あるテーブル
CREATE TABLE test(
s TEXT,
update_time TIMESTAMP
) ;
--あるテーブルの更新ログテーブル
CREATE TABLE test_log(
s TEXT,
update_time TIMESTAMP,
log_user TEXT,
log_time TIMESTAMP
) ;
というテーブルを定義して
CREATE FUNCTION test_func() RETURNS TRIGGER AS '
BEGIN
INSERT INTO test_log
VALUES(old.s,old.update_time,CURRENT_USER,''now'');
RETURN NEW;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER test_trigger AFTER UPDATE OR DELETE ON test
FOR EACH ROW EXECUTE PROCEDURE test_func();
とトリガを定義しました。
まず1行データを追加して更新します。
# INSERT INTO test VALUES('a1','now');
INSERT 117494 1
# UPDATE test SET s = 'a2',update_time = 'now';
UPDATE 1
# SELECT * FROM test;
s | update_time
----+----------------------------
a2 | 2003-11-18 16:09:12.353329
(1 行)
# SELECT * FROM test_log;
s | update_time | log_user | log_time
----+---------------------------+----------+----------------------------
a1 | 2003-11-18 16:07:57.54663 | test | 2003-11-18 16:09:12.353329
(1 行)
少し時間を置いてからさらに更新します。
# SELECT now();
now
------------------------------
2003-11-18 16:09:28.89699+09
(1 行)
# UPDATE test SET s = 'a3',update_time = 'now';
UPDATE 1
# SELECT * FROM test;
s | update_time
----+----------------------------
a3 | 2003-11-18 16:09:28.897903
(1 行)
# SELECT * FROM test_log;
s | update_time | log_user | log_time
----+----------------------------+----------+----------------------------
a1 | 2003-11-18 16:07:57.54663 | test | 2003-11-18 16:09:12.353329
a2 | 2003-11-18 16:09:12.353329 | test | 2003-11-18 16:09:12.353329
(2 行)
すると、test_log.log_timeには、同じ時間が記入されます。
さらに更新しても同じ時間となります。
# UPDATE test SET s = 'a4',update_time = 'now';
UPDATE 1
# SELECT * FROM test_log;
s | update_time | log_user | log_time
----+----------------------------+----------+----------------------------
a1 | 2003-11-18 16:07:57.54663 | test | 2003-11-18 16:09:12.353329
a2 | 2003-11-18 16:09:12.353329 | test | 2003-11-18 16:09:12.353329
a3 | 2003-11-18 16:09:28.897903 | test | 2003-11-18 16:09:12.353329
(3 行)
一度psqlを終了して起動して同じ事を実行すると
# UPDATE test SET s = 'a5',update_time = 'now';
UPDATE 1
# SELECT * FROM test_log;
s | update_time | log_user | log_time
----+----------------------------+----------+----------------------------
a1 | 2003-11-18 16:07:57.54663 | test | 2003-11-18 16:09:12.353329
a2 | 2003-11-18 16:09:12.353329 | test | 2003-11-18 16:09:12.353329
a3 | 2003-11-18 16:09:28.897903 | test | 2003-11-18 16:09:12.353329
a4 | 2003-11-18 16:09:55.772272 | test | 2003-11-18 16:10:12.318736
(4 行)
時間が変わります。
--ここまで-----------------------------------------------------
いろいろと試していたら、以下のようにtest_log.log_timeを
「DEFAULT CURRENT_TIMESTAMP」とすると、意図したとおりに
動作する事がわかりました。
TRIGGERの中で使用する「now」と「DEFAULT CURRENT_TIMESTAMP」
では、何か意味が異なるのでしょうか。
CREATE TABLE test_log(
s TEXT,
update_time TIMESTAMP,
log_user TEXT DEFAULT CURRENT_USER ,
log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ;
CREATE FUNCTION test_func() RETURNS TRIGGER AS '
BEGIN
INSERT INTO test_log(s,update_time)
VALUES(old.s,old.update_time);
RETURN NEW;
END;
' LANGUAGE 'plpgsql';
以上、よろしくお願いします。
pgsql-jp メーリングリストの案内