Unterschied zwischen now () und current_timestamp


45

In PostgreSQL, verwende ich die now()und current_timestampFunktion , und ich sehe keinen Unterschied:

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

Vermisse ich etwas?

Antworten:


54

Es gibt keinen Unterschied. Drei Zitate aus dem Handbuch:

1)

Diese SQL-Standardfunktionen geben alle Werte basierend auf der Startzeit der aktuellen Transaktion zurück:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()ist äquivalent zu CURRENT_TIMESTAMP, wird aber benannt, um deutlich zu machen, was es zurückgibt.

3)

now()ist ein traditionelles PostgreSQL-Äquivalent zu transaction_timestamp().

Meine kühne Betonung. CURRENT_TIMESTAMP, transaction_timestamp()Und now()tun genau das gleiche. CURRENT_TIMESTAMPist eine syntaktische Kuriosität für eine Funktion ohne nachfolgende Klammern. Das entspricht dem SQL-Standard.

Wenn Sie in einer SQL-Anweisung keinen Spaltenalias für einen Funktionsaufruf deklarieren, wird standardmäßig der Name der Funktion verwendet. Intern wird das Standard-SQL CURRENT_TIMESTAMPmit implementiert now(). Bis zu Postgres 9.6, der im resultierenden Spaltennamen angezeigt wird , der "jetzt" lautete, aber in Postgres 10 in "current_timestamp" geändert wurde.

transaction_timestamp() tut dasselbe, aber dies ist eine richtige Postgres-Funktion, daher war der Standardalias immer "transaction_timestamp".

Verwechseln Sie keine dieser Funktionen mit der speziellen Eingangskonstante'now' . Dies ist nur eine von mehreren Abkürzungen für bestimmte Datums- / Zeit- / Zeitstempelwerte, die im Handbuch zitiert werden:

... die beim Lesen in normale Datums- / Zeitwerte umgewandelt werden. (Insbesondere nowund verwandte Zeichenfolgen werden in einen bestimmten Zeitwert konvertiert, sobald sie gelesen werden.) Alle diese Werte müssen in einfache Anführungszeichen eingeschlossen werden, wenn sie in SQL-Befehlen als Konstanten verwendet werden.

Es kann zu der Verwirrung führen, dass (bis mindestens Postgres 12) eine beliebige Anzahl von führenden und nachfolgenden Leerzeichen und Klammern ( {[( )]}) von diesen speziellen Eingabewerten abgeschnitten werden. Also 'now()'::timestamptz- oder nur 'now()'wenn keine explizite Typumwandlung erforderlich ist - ist auch gültig und wird now() in den meisten Kontexten mit demselben Zeitstempel wie die Funktion ausgewertet . Aber das sind Konstanten und normalerweise nicht das, was Sie zum Beispiel als Spaltenvorgabe wollen.

db <> fiddle here
Alte SQL-Geige

Bemerkenswerte Alternativen sind statement_timestamp()und clock_timestamp(). Das Handbuch:

statement_timestamp()Gibt die Startzeit der aktuellen Anweisung zurück (genauer gesagt den Zeitpunkt des Empfangs der letzten Befehlsnachricht vom Client). [...]
clock_timestamp()gibt die aktuelle Uhrzeit zurück und daher ändert sich ihr Wert auch innerhalb eines einzelnen SQL-Befehls.

Hinweis: statement_timestamp()ist STABLEwie oben (gibt immer den gleichen Wert innerhalb des gleichen SQL-Befehls zurück). Muss aber clock_timestamp()unbedingt nur sein VOLATILE. Der Unterschied kann erheblich sein.


Aber macht es einen Unterschied für die Abfrageoptimierung? wird jetzt () für jede Zeile ausgeführt in where items.createddate > now():?
Santiago Arizti

3
@santiagoarizti: Nr. now()ist definiert, STABLEweil der Wert (die Startzeit der aktuellen Transaktion) innerhalb derselben Transaktion gleich ist. Ich Ihr Beispiel now()wird nur einmal ausgeführt (im Gegensatz zu clock_timestamp()zum Beispiel).
Erwin Brandstetter

3

Da sie bei ordnungsgemäßer Verwendung keinen funktionalen Unterschied aufweisen, werden sie unterschiedlich besetzt:

'now()'anerkannt (genau wie 'today'oder 'now'):

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

'CURRENT_TIMESTAMP'gibt lustige fehler von dunklen kanten

Hinweis: Ab PostgreSQL-Version 7.2 wird 'current' nicht mehr als Datums- / Zeitkonstante unterstützt

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

und 'transaction_timestamp()'wird einfach nicht als Zeitstempel mit tz-Wert erkannt:

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

Bitte frag nicht, warum du gießen würdest 'now()' as timestamp. Ich habe gesehen, where timestamp_column = 'now()'anstatt where timestamp_column = now()in People-Code, so dachte, diese Klarstellung wäre lustig Tatsache und eine gute Ergänzung zu Erwins Antwort.


Das ist ein Missverständnis. Die Eingabezeichenfolge'now()' ähnelt der Funktion now()auf der Oberfläche, ist jedoch ansonsten nicht direkt verknüpft. 'now'ist eine Konstante, die zur Startzeit der aktuellen Transaktion ausgewertet wird . Trailing Parens werden ignoriert. Der Versuch , die Saiten zu werfen 'CURRENT_TIMESTAMP'oder 'transaction_timestamp()'zu timestampin ähnlicher Weise versagt, denn das ist nur Unsinn. Beides hat nichts mit den entsprechenden Funktionen zu tun.
Erwin Brandstetter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.