※ 執筆時点の2022年05月でのPostgreSQL 13に基づいて書きましたが、9以降のPostgreSQLで一貫して同じように扱われているので問題ないかと。
現在日時を示すものには、いろんな表現があります
PostgreSQL 13の日本語ドキュメントで、9.9.4. 現在の日付/時刻を見ていて気づいたのでメモしておきます。
PostgreSQLでは様々な現在日時を示す表現があるのです。
CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, LOCALTIMESTAMP
SELECT
CURRENT_DATE,
CURRENT_TIME,
CURRENT_TIMESTAMP,
CURRENT_TIME(1),
CURRENT_TIMESTAMP(1),
LOCALTIME,
LOCALTIMESTAMP,
LOCALTIME(1),
LOCALTIMESTAMP(1)
この処理系の場合は、秒以下6桁まで提供するものの、精度を指定することで指定桁での丸め処理が行われることがわかりました。
「+09」がついているのは、タイムゾーンつきということですね。
transaction_timestamp(), statement_timestamp(), clock_timestamp(), timeofday(), now()
説明を丸ごと引用しておきます:
transaction_timestamp()はCURRENT_TIMESTAMPと等価ですが、明確に何を返すかを反映する名前になっています。
statement_timestamp()は現在の文の実行開始時刻を返すものです(より具体的にいうと、直前のコマンドメッセージをクライアントから受け取った時刻です)。 statement_timestamp()およびtransaction_timestamp()はトランザクションの最初のコマンドでは同じ値を返しますが、その後に引き続くコマンドでは異なる可能性があります。
clock_timestamp()は実際の現在時刻を返しますので、その値は単一のSQLコマンドであっても異なります。
timeofday()はPostgreSQLの歴史的な関数です。 clock_timestamp()同様、実際の現在時刻を返しますが、timestamp with time zone型の値ではなく、整形されたtext文字列を返します。
now()はtransaction_timestamp()と同じもので、伝統的なPostgreSQL関数です。
SELECT
transaction_timestamp(), statement_timestamp(), clock_timestamp(), timeofday(), now()
;
このSELECT文を単発でやってもあまり意味がなく、説明にあるようにトランザクション処理の中で使えばいろいろな差が出てくるものになってます。
使い分けを考える
INSERT文やUPDATE文を実行したリアルな時刻を記録したい(例えばcreate_atやupdate_atとか)なら、transaction_timestamp()とclock_timestamp()のどちらでしょうか。
考え方次第だとは思うのですが、一連のデータ更新処理を一括りとして捉えるなら、transaction_timestamp()を使うのが筋だと思えます。 複数のテーブルを横断するような長い処理で、最初の方と最後の方で日時がズレないのはこちらのtransaction_timestamp()です。
一方、リアルな時刻にこだわるならclock_timestamp()になりそうです。 特定のクエリーの処理時間を計測する、みたいなのにも使えるかもしれません。