Diferencia entre now () y current_timestamp

45

En PostgreSQL, utilizo el now()y current_timestampla función y no veo ninguna diferencia:

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

¿Me estoy perdiendo de algo?

JohnMerlino
fuente

Respuestas:

54

No hay diferencia. Tres citas del manual:

1)

Estas funciones estándar de SQL todos los valores de retorno se basan en la hora de inicio de la transacción actual:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()es equivalente a CURRENT_TIMESTAMP, pero se nombra para reflejar claramente lo que devuelve.

3)

now()es un tradicional PostgreSQL equivalente a transaction_timestamp().

El énfasis en negrita es mío. CURRENT_TIMESTAMP, transaction_timestamp()y now()hacer exactamente lo mismo. CURRENT_TIMESTAMPes una rareza sintáctica para una función, que no tiene par de paréntesis finales. Eso está de acuerdo con el estándar SQL.

Si no declara un alias de columna para una llamada a una función en una instrucción SQL, el alias predeterminado es el nombre de la función. Internamente, el SQL estándar CURRENT_TIMESTAMPse implementa con now(). Hasta Postgres 9.6 que se muestra en el nombre de la columna resultante , que era "ahora", pero cambió a "current_timestamp" en Postgres 10.

transaction_timestamp() hace lo mismo, pero esta es una función adecuada de Postgres, por lo que el alias predeterminado siempre ha sido "transaction_timestamp".

No , no confundir a cualquiera de estas funciones con el especial constante de entrada'now' . Esa es solo una de las varias abreviaturas de notación para valores específicos de fecha / hora / marca de tiempo, citando el manual:

... que se convertirá en valores normales de fecha / hora cuando se lea. (En particular, nowy las cadenas relacionadas se convierten a un valor de tiempo específico tan pronto como se leen). Todos estos valores deben estar entre comillas simples cuando se usan como constantes en los comandos SQL.

Puede aumentar la confusión de que (hasta al menos Postgres 12) cualquier número de espacios iniciales y finales y corchetes ( {[( )]}) se recortan de esos valores de entrada especiales. Entonces 'now()'::timestamptz, o simplemente 'now()'donde no se requiere conversión de tipo explícito, también es válido y se evalúa con la misma marca de tiempo que la función now() en la mayoría de los contextos . Pero esas son constantes y, por lo general, no son lo que desea como columna predeterminada, por ejemplo.

db <> violín aquí
Viejo violín de SQL

Las alternativas notables son statement_timestamp()y clock_timestamp(). El manual:

statement_timestamp()devuelve la hora de inicio de la declaración actual (más específicamente, la hora de recepción del último mensaje de comando del cliente). [...]
clock_timestamp()devuelve la hora actual real y, por lo tanto, su valor cambia incluso dentro de un solo comando SQL.

Nota: statement_timestamp()es STABLEcomo el anterior (siempre devuelve el mismo valor dentro del mismo comando SQL). Pero clock_timestamp()necesariamente es solo VOLATILE. La diferencia puede ser significativa.

Erwin Brandstetter
fuente
pero, ¿hay alguna diferencia en la optimización de consultas? ahora () se ejecutará para cada fila en where items.createddate > now():?
santiago arizti
3
@santiagoarizti: No. now()se define STABLEporque se evalúa al mismo valor (la hora de inicio de la transacción actual) dentro de la misma transacción. I su ejemplo, now()se ejecuta una sola vez (a diferencia de clock_timestamp()por ejemplo).
Erwin Brandstetter
3

Además de que no tienen una diferencia funcional cuando los usa correctamente, se lanzan de manera diferente:

'now()'Reconocido (como 'today'o 'now'):

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

'CURRENT_TIMESTAMP'da error gracioso de bordes oscuros

Nota: A partir de PostgreSQL versión 7.2, 'actual' ya no se admite como una constante de fecha / hora

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

y 'transaction_timestamp()'simplemente no se reconoce como marca de tiempo con el valor tz:

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

Por favor, no preguntes por qué lanzarías 'now()' as timestamp. Lo he visto en where timestamp_column = 'now()'lugar de where timestamp_column = now()en el código de personas, por lo que pensé que esta aclaración sería un hecho curioso y una buena adición a la respuesta de Erwin.

Vao Tsun
fuente
Este es un malentendido. La cadena de entrada se'now()' parece a la función now()en la superficie, pero de lo contrario no está directamente relacionada. 'now'es una evaluación constante del tiempo de inicio de la transacción actual . Los parens finales se ignoran. El intento de lanzar las cuerdas 'CURRENT_TIMESTAMP'o 'transaction_timestamp()'de timestampmanera similar falla, porque eso no tiene sentido. Ninguno de los dos está relacionado con las funciones correspondientes.
Erwin Brandstetter