Differenza tra now () e current_timestamp


45

In PostgreSQL, io uso la now()e current_timestampla funzione e non vedo alcuna differenza:

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

Mi sto perdendo qualcosa?

Risposte:


54

Non c'è differenza. Tre citazioni dal manuale:

1)

Queste funzioni standard SQL restituiscono tutti i valori in base all'ora di inizio della transazione corrente:
... ...
CURRENT_TIMESTAMP

2)

transaction_timestamp()è equivalente a CURRENT_TIMESTAMP, ma è chiamato per riflettere chiaramente ciò che restituisce.

3)

now()è un tradizionale PostgreSQL equivalente a transaction_timestamp().

Enorme enfasi sulla mia. CURRENT_TIMESTAMP, transaction_timestamp()E now()fare esattamente lo stesso. CURRENT_TIMESTAMPè una stranezza sintattica per una funzione, senza parentesi finali. Questo è secondo lo standard SQL.

Se non si dichiara un alias di colonna per una chiamata di funzione in un'istruzione SQL, l'alias viene impostato automaticamente sul nome della funzione. Internamente, lo standard-SQL CURRENT_TIMESTAMPè implementato con now(). Fino a Postgres 9.6 che mostra il nome della colonna risultante , che era "adesso", ma cambiato in "current_timestamp" in Postgres 10.

transaction_timestamp() fa lo stesso, ma questa è una funzione Postgres corretta, quindi l'alias predefinito è sempre stato "transaction_timestamp".

Do Non confondete una di queste funzioni con la speciale costante di ingresso'now' . Questo è solo uno dei numerosi short notazionali per specifici valori di data / ora / timestamp, citando il manuale:

... che verranno convertiti in valori di data / ora ordinari durante la lettura. (In particolare, nowe le stringhe correlate vengono convertite in un valore temporale specifico non appena vengono lette.) Tutti questi valori devono essere racchiusi tra virgolette singole quando utilizzati come costanti nei comandi SQL.

Può aggiungere alla confusione che (fino ad almeno Postgres 12) qualsiasi numero di spazi e parentesi ( {[( )]}) iniziali e finali sia tagliato da quegli speciali valori di input. Quindi 'now()'::timestamptz- o solo 'now()'dove non è richiesto alcun cast di tipo esplicito - è anche valido e capita di valutare allo stesso timestamp della funzione now() nella maggior parte dei contesti . Ma quelle sono costanti e in genere non sono ciò che vuoi come colonna predefinita per esempio.

db <> violino qui
Vecchio violino SQL

Notevoli alternative sono statement_timestamp()e clock_timestamp(). Il manuale:

statement_timestamp()restituisce l'ora di inizio dell'istruzione corrente (in particolare, l'ora di ricezione dell'ultimo messaggio di comando dal client). [...]
clock_timestamp()restituisce l'ora corrente attuale, e quindi il suo valore cambia anche all'interno di un singolo comando SQL.

Nota: statement_timestamp()è STABLEcome sopra (restituisce sempre lo stesso valore all'interno dello stesso comando SQL). Ma clock_timestamp()è necessariamente solo VOLATILE. La differenza può essere significativa.


ma, fa differenza per l'ottimizzazione delle query? sarà ora () eseguito per ogni riga in where items.createddate > now():?
santiago arizti,

3
@santiagoarizti: No. now()è definito STABLEperché valuta lo stesso valore (l'ora di inizio della transazione corrente) all'interno della stessa transazione. Il tuo esempio now()è eseguito una sola volta (al contrario di clock_timestamp()per esempio).
Erwin Brandstetter,

3

Inoltre, quando non vengono utilizzati correttamente, non hanno alcuna differenza funzionale, ma vengono espressi in modo diverso:

'now()'ricongiunto (proprio come 'today'o 'now'):

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

'CURRENT_TIMESTAMP'dà un errore divertente dai bordi scuri

Nota: a partire da PostgreSQL versione 7.2, "corrente" non è più supportata come costante data / ora

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

e non 'transaction_timestamp()'viene semplicemente ricongiunto come data / ora con valore tz:

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

Per favore, non chiedere perché dovresti lanciare 'now()' as timestamp. Ho visto where timestamp_column = 'now()'invece where timestamp_column = now()nel codice delle persone, quindi ho pensato che questo chiarimento sarebbe stato un fatto divertente e una buona aggiunta alla risposta di Erwin.


Questo è un malinteso. La stringa di input'now()' è simile alla funzione now()in superficie, ma non è direttamente correlata in altro modo. 'now'è una costante valutazione dell'ora di inizio della transazione corrente . Le parentesi finali vengono ignorate. Il tentativo di gettare le corde 'CURRENT_TIMESTAMP'o 'transaction_timestamp()'per timestampin modo simile non riesce, perché è solo una sciocchezza. Nessuno dei due è correlato alle funzioni corrispondenti.
Erwin Brandstetter,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.