Diferença entre now () e current_timestamp

45

Em PostgreSQL, eu uso o now()e current_timestampfunção e não vejo diferença:

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

Estou esquecendo de algo?

JohnMerlino
fonte

Respostas:

54

Não há diferença. Três citações do manual:

1)

Todas essas funções padrão do SQL retornam valores com base no horário de início da transação atual:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()é equivalente a CURRENT_TIMESTAMP, mas é nomeado para refletir claramente o que retorna.

3)

now()é um equivalente tradicional do PostgreSQL transaction_timestamp().

Negrito ênfase minha. CURRENT_TIMESTAMP, transaction_timestamp()E now()fazer exatamente o mesmo. CURRENT_TIMESTAMPé uma singularidade sintática para uma função, sem parênteses à direita. Isso está de acordo com o padrão SQL.

Se você não declarar um alias de coluna para uma chamada de função em uma instrução SQL, o alias usará como padrão o nome da função. Internamente, o SQL padrão CURRENT_TIMESTAMPé implementado com now(). Até o Postgres 9.6, exibido no nome da coluna resultante , que era "agora", mas alterado para "current_timestamp" no Postgres 10.

transaction_timestamp() faz o mesmo, mas esta é uma função apropriada do Postgres, portanto o alias padrão sempre foi "transaction_timestamp".

Você não confundir qualquer uma destas funções com o especial constante de entrada'now' . Essa é apenas uma das várias atalhos notáveis ​​para valores específicos de data / hora / carimbo de data / hora, citando o manual:

... que serão convertidos em valores comuns de data / hora quando lidos. (Em particular, nowas seqüências de caracteres relacionadas e são convertidas em um valor de tempo específico assim que são lidas.) Todos esses valores precisam ser colocados entre aspas simples quando usados ​​como constantes nos comandos SQL.

Isso pode aumentar a confusão de que (até pelo menos o Postgres 12) qualquer número de espaços à esquerda e à direita e colchetes ( {[( )]}) são aparados a partir desses valores de entrada especiais. Portanto 'now()'::timestamptz- ou apenas 'now()'onde nenhum tipo explícito de conversão é necessário - também é válido e passa a ser avaliado com o mesmo registro de data e hora da função now() na maioria dos contextos . Mas essas são constantes e normalmente não são o que você deseja como padrão da coluna, por exemplo.

db <> violino aqui Violino SQL
velho

Alternativas notáveis ​​são statement_timestamp()e clock_timestamp(). O manual:

statement_timestamp()retorna a hora de início da instrução atual (mais especificamente, a hora do recebimento da última mensagem de comando do cliente). [...]
clock_timestamp()retorna a hora atual real e, portanto, seu valor muda mesmo dentro de um único comando SQL.

Nota: statement_timestamp()é STABLEcomo o acima (sempre retorna o mesmo valor dentro do mesmo comando SQL). Mas clock_timestamp()necessariamente é apenas VOLATILE. A diferença pode ser significativa.

Erwin Brandstetter
fonte
mas, isso faz diferença na otimização de consultas? now () será executado para cada linha em where items.createddate > now():?
santiago arizti 21/02
3
@santiagoarizti: Não. now()é definido STABLEporque é avaliado com o mesmo valor (a hora de início da transação atual) dentro da mesma transação. No seu exemplo, now()é executado apenas uma vez (em oposição a, clock_timestamp()por exemplo).
Erwin Brandstetter
3

Além disso, eles não têm diferença funcional quando você os usa adequadamente, eles são convertidos de maneira diferente:

'now()'recongnized (exatamente como 'today'ou 'now'):

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

'CURRENT_TIMESTAMP'erro engraçado de bordas escuras

Nota: A partir do PostgreSQL versão 7.2, 'current' não é mais suportado como uma constante de data / hora

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

e 'transaction_timestamp()'não é recongizado como carimbo de data / hora com 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, não pergunte por que você lançaria 'now()' as timestamp. Vi em where timestamp_column = 'now()'vez do where timestamp_column = now()código das pessoas, então pensei que esse esclarecimento seria um fato engraçado e um bom complemento para a resposta de Erwin.

Vao Tsun
fonte
Isso é um mal entendido. A sequência de entrada'now()' é semelhante à função now()na superfície, mas não está diretamente relacionada de outra forma. 'now'é uma avaliação constante da hora de início da transação atual . Parênteses à direita são ignorados. A tentativa de transmitir as cordas 'CURRENT_TIMESTAMP'ou 'transaction_timestamp()'de timestampmaneira semelhante falha, porque isso é apenas um absurdo. Nenhum dos dois está relacionado às funções correspondentes.
Erwin Brandstetter