Différence entre now () et current_timestamp

45

Dans PostgreSQL, j'utilise la now()et current_timestampfonction et je ne vois aucune différence:

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

Est-ce que je manque quelque chose?

JohnMerlino
la source

Réponses:

54

Il n'y a pas de différence. Trois citations du manuel:

1)

Ces fonctions standard SQL renvoient toutes des valeurs en fonction de l'heure de début de la transaction en cours:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()est équivalent à CURRENT_TIMESTAMP, mais est nommé pour refléter clairement ce qu'il retourne.

3)

now()est un équivalent PostgreSQL traditionnel à transaction_timestamp().

Gras accent mien. CURRENT_TIMESTAMP, transaction_timestamp()Et now()faire exactement la même chose. CURRENT_TIMESTAMPest une bizarrerie syntaxique pour une fonction, sans paire de parenthèses. C'est selon le standard SQL.

Si vous ne déclarez pas d'alias de colonne pour un appel de fonction dans une instruction SQL, l'alias utilise par défaut le nom de la fonction. En interne, le SQL standard CURRENT_TIMESTAMPest implémenté avec now(). Jusqu'à Postgres 9.6, le nom de la colonne résultante était "now", mais "current_timestamp" dans Postgres 10.

transaction_timestamp() fait de même, mais celle-ci est une fonction Postgres appropriée, de sorte que l'alias par défaut a toujours été "transaction_timestamp".

Ne pas confondre l' une de ces fonctions avec la spéciale constante d'entrée'now' . Ce n'est qu'un des raccourcis de notation pour des valeurs de date / heure / horodatage spécifiques, citant le manuel:

... qui seront convertis en valeurs date / heure ordinaires lors de la lecture. (En particulier, nowles chaînes associées sont converties en une valeur temporelle spécifique dès leur lecture.) Toutes ces valeurs doivent être placées entre guillemets simples lorsqu'elles sont utilisées comme constantes dans des commandes SQL.

Cela peut ajouter à la confusion que (jusqu'à au moins Postgres 12) un nombre quelconque d'espaces de début et de fin et des crochets ( {[( )]}) sont coupés de ces valeurs d'entrée spéciales. Donc 'now()'::timestamptz- ou juste 'now()'là où aucun transtypage de type explicite n'est requis - est également valide et a pour résultat d'évaluer le même horodatage que la fonction now() dans la plupart des contextes . Mais ce sont des constantes et généralement pas ce que vous voulez comme colonne par défaut par exemple.

db <> fiddle here
Vieux violon SQL

Des alternatives notables sont statement_timestamp()et clock_timestamp(). Le manuel:

statement_timestamp()renvoie l'heure de début de l'instruction en cours (plus précisément l'heure de réception du dernier message de commande du client). [...]
clock_timestamp()renvoie l'heure actuelle et, par conséquent, sa valeur change même au sein d'une seule commande SQL.

Note: statement_timestamp()est STABLEcomme ci - dessus (retourne toujours la même valeur dans la même commande SQL). Mais clock_timestamp()est nécessairement seulement VOLATILE. La différence peut être significative.

Erwin Brandstetter
la source
mais cela fait-il une différence pour l'optimisation des requêtes? Est-ce que now () sera exécuté pour chaque ligne dans where items.createddate > now():?
santiago arizti
3
@santiagoarizti: Non. N ° now()est défini STABLEcar il a la même valeur (l'heure de début de la transaction en cours) dans la même transaction. Dans votre exemple, now()n’est exécuté qu’une fois (par opposition à clock_timestamp()par exemple).
Erwin Brandstetter
3

De plus, ils n’ont aucune différence fonctionnelle lorsque vous les utilisez correctement, ils sont exprimés différemment:

'now()'reconnu (comme 'today'ou 'now'):

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

'CURRENT_TIMESTAMP'donne une erreur amusante des bords sombres

Remarque: à partir de la version 7.2 de PostgreSQL, 'actuel' n'est plus pris en charge en tant que constante de date / heure.

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

et 'transaction_timestamp()'n'est tout simplement pas reconnu comme horodatage avec la valeur tz:

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

S'il vous plaît ne demandez pas pourquoi voudriez-vous lancer 'now()' as timestamp. J'ai vu à la where timestamp_column = 'now()'place du where timestamp_column = now()code de personnes, alors je pensais que cette clarification serait un fait amusant et un bon ajout à la réponse d'Erwin.

Vao Tsun
la source
C'est un malentendu. La chaîne en entrée'now()' ressemble à la fonction now()sur la surface, mais n'est pas directement liée autrement. 'now'est une évaluation constante de l' heure de début de la transaction en cours . Les parens de fin sont ignorés. La tentative de lancer les cordes 'CURRENT_TIMESTAMP'ou 'transaction_timestamp()'de timestampmanière similaire échoue, parce que c'est absurde. Ni est liée aux fonctions correspondantes.
Erwin Brandstetter le