now()とcurrent_timestampの違い


45

PostgreSQLでは、now()and current_timestamp関数を使用しますが、違いはありません。

# SELECT now(), current_timestamp;
              now               |              now               
--------------------------------+--------------------------------
 04/20/2014 19:44:27.215557 EDT | 04/20/2014 19:44:27.215557 EDT
(1 row)

何か不足していますか?

回答:


54

違いはありません。マニュアルからの3つの引用:

1)

これらのSQL標準関数はすべて、現在のトランザクションの開始時間に基づいて値を返します
。... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()はと同等ですがCURRENT_TIMESTAMP、返されるものを明確に反映するように名前が付けられます。

3)

now()はに相当する伝統的なPostgreSQLですtransaction_timestamp()

大胆な強調鉱山。CURRENT_TIMESTAMPtransaction_timestamp()now()やる正確に同じ。CURRENT_TIMESTAMPは、括弧の末尾のペアを持たない、関数の構文上の奇妙さです。これは、SQL標準に従っています。

SQLステートメントで関数呼び出しの列エイリアスを宣言しない場合、エイリアスはデフォルトで関数名になります。内部的に、標準SQLはでCURRENT_TIMESTAMP実装されていnow()ます。結果の列名に表示されるPostgres 9.6まで。これは「現在」でしたが、Postgres 10では「current_timestamp」に変更されました。

transaction_timestamp() 同じことをしますが、これは適切なPostgres関数なので、デフォルトのエイリアスは常に「transaction_timestamp」です。

これらの関数を特別な入力定数と混同しないでください。これは、マニュアルを引用して、特定の日付/時刻/タイムスタンプ値のいくつかの表記上の略記法の1つにすぎません'now'

...読み取り時に通常の日付/時刻値に変換されます。(特に、now関連する文字列は、読み取られるとすぐに特定の時間値に変換されます。)これらの値はすべて、SQLコマンドで定数として使用する場合、単一引用符で囲む必要があります。

(少なくともPostgres 12まで)任意の数の先頭および末尾のスペースと角かっこ({[( )]})がこれらの特別な入力値から削除されるという混乱を招く可能性があります。そのため、'now()'::timestamptzまたは'now()'明示的な型キャストが不要な場合も有効であり、たまたまnow() ほとんどのコンテキストで関数と同じタイムスタンプに評価されます。ただし、これらは定数であり、通常、たとえば列のデフォルトとして必要なものではありません

db <> fiddle here
古いSQL fiddle

注目すべき選択肢があるstatement_timestamp()clock_timestamp()マニュアル:

statement_timestamp()現在のステートメントの開始時間(より具体的には、クライアントからの最新のコマンドメッセージの受信時間)を返します。[...]
clock_timestamp()は実際の現在時刻を返すため、その値は単一のSQLコマンド内でも変化します。

注:statement_timestamp()あるSTABLE上記は(常に同じSQLコマンド内で同じ値を返す)として。しかし、clock_timestamp()必ずですVOLATILE。違いが大きい場合があります。


しかし、それはクエリの最適化に違いをもたらしますか?now()は、次のすべての行に対して実行されます:where items.createddate > now()
サンティアゴarizti

3
@santiagoarizti:同じトランザクション内で同じ値(現在のトランザクションの開始時間)に評価now()されるSTABLEため、No は定義されています。あなたの例でnow()は、(たとえば)1回だけ実行さclock_timestamp()れます。
アーウィンブランドステッター

3

これらを適切に使用しても機能的な違いはないことに加えて、キャスト方法も異なります。

'now()'再認識('today'またはのように'now'):

b=# select 'now()'::timestamptz;
          timestamptz
-------------------------------
 2016-12-09 16:31:35.942243+00
(1 row)

'CURRENT_TIMESTAMP'暗いエッジから面白いエラーを与えます

注:PostgreSQLバージョン7.2以降、「current」は日付/時刻定数としてサポートされなくなりました

b=# select 'CURRENT_TIMESTAMP'::timestamptz;
ERROR:  date/time value "current" is no longer supported
LINE 1: select 'CURRENT_TIMESTAMP'::timestamptz;
               ^

そして、'transaction_timestamp()'単にtz値を持つタイムスタンプとして認識されません:

b=# select 'transaction_timestamp()'::timestamptz;
ERROR:  invalid input syntax for type timestamp with time zone: "transaction_timestamp()"
LINE 1: select 'transaction_timestamp()'::timestamptz;
               ^

なぜキャストするのか聞かないでください'now()' as timestamp。私は人々のコードのwhere timestamp_column = 'now()'代わりに見たwhere timestamp_column = now()ので、この説明は面白い事実であり、アーウィンの答えに良い追加だと思った。


これは誤解です。入力文字列は、'now()'関数に似now()表面上が、直接それ以外の場合は関係ありません。'now'は、現在のトランザクションの開始時間を評価する定数です。末尾の括弧は無視されます。文字列にキャストしようとし'CURRENT_TIMESTAMP'たり'transaction_timestamp()'するとtimestampそれはちょうどナンセンスだから、同様の方法では、失敗します。どちらも対応する機能とは関係ありません。
アーウィンブランドステッター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.