[pgsql-jp: 31510] Re: TRIGGERの中で使用する「 now」について
bxcel
bxcel @ prophet.jp
2003年 11月 19日 (水) 14:56:41 JST
松本と申します。
> たぶん、
> CREATE or replace 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';
>
> のように書き直されたかと思いますが、正解は
>
> VALUES(old.s,old.update_time,CURRENT_USER,now());
>
> です。
あ....、全くその通りです。「''now()''」としてました。
> ''now()'' とすると、この PL/pgSQL が初めて実行された時の日時
> になってしまいます。初回実行時にコンパイルされ、'' で囲まれ
> ているため固定された文字列(now()の実行結果)が入ります。
なるほど、そういう仕組みだったんですね。理解不足でした。
シーラカンス本のトリガ用関数の定義を参考にさせて頂いたのですが、
もしかしたら''で囲むのがなんか影響しているのかと思い、
VALUES(old.s,old.update_time,CURRENT_USER,now);
としてみたりもしたのですが、エラーとなってしまったので、
''で囲むものと思い込んでおりました。
関数とリテラル値に関して理解できてませんでした。
鈴木さんに教えてもらった時に気づくべきでしたね。
あと「初回実行時にコンパイルされ」についてですが、これは
「postgresを起動した後の初回」ではなく、コネクション単位
なんですね。
期待した通りの結果となっていた時もあったので、おかしいなぁ
と思っていたのですが、コネクションプールの使いまわし具合?
だったんですね。
同じく鈴木さんに教えてもらったマニュアルを読み返してみると
最後の方の「Note:」に「定数が解釈された時、システムが
now を timestamp に変換するので....」という記述があり
ここからも私が期待した結果と違う理由が読み取れましたね。
> ・・・・う。色々と実験されてるようですね。
> 外してたらごめんなさい。
レベルの低さをさらしちゃいまして恥ずかしいです....
とっても遠回りしちゃってましたね。
ありがとうございました。
pgsql-jp メーリングリストの案内