I tipi di dati e le differenze tra loro sono nella documentazione . La versione breve è:
- DATE ha una precisione fino a un secondo senza supporto per il fuso orario;
- TIMESTAMP ha una precisione fino a frazioni di secondo (fino a nove cifre decimali, ma il tuo sistema operativo influisce anche su questo), ancora senza il supporto del fuso orario;
- TIMESTAMP WITH TIME ZONE ha la stessa precisione di TIMESTAMP ma ha anche il supporto del fuso orario, come suggerisce il nome;
- TIMESTAMP CON FUSO ORARIO LOCALE regola il valore memorizzato da e verso il fuso orario locale della sessione di creazione/interrogazione.
Potresti trovare questo articolo anche interessante.
Ogni volta che si confrontano i valori datetime archiviati nel database, è necessario utilizzare valori dello stesso tipo di dati per il confronto. Non è necessario convertire tutti i valori nella colonna per il confronto, soprattutto se la colonna è indicizzata. Se hai una colonna DATE, confronta con una DATE - non confrontare come una stringa e non fare affidamento su conversione di una stringa. Quando lo fai:
WHERE date_col BETWEEN '01-JAN-1990' AND '01-JAN-2000'
fai affidamento sul fatto che il tuo NLS_DATE_FORMAT sia DD-MON-YYYY e il tuo NLS_DATE_LANGUAGE sia inglese. Se qualcun altro esegue la stessa query in un'altra sessione, le sue impostazioni potrebbero causare il fallimento della query (o, in alcuni casi, fornire risultati errati, che possono essere peggiori). Per evitare il problema della lingua è meglio usare i numeri dei mesi piuttosto che i nomi. Se hai una variabile stringa da confrontare dovresti usare TO_DATE()
per convertire la stringa in una DATE utilizzando una maschera di formato nota fissa, non fare affidamento su NLS. Se hai un valore fisso puoi fare lo stesso, oppure puoi usare un data letterale
, che è più breve e inequivocabile.
Con il formato che hai utilizzato includi anche tutte le righe che hanno una colonna impostata sulla mezzanotte del 1 gennaio 2000, ma non più tardi di quel giorno. Potrebbe essere quello che vuoi, ma assicurati di capire come BETWEEN
lavori. Se stai effettivamente cercando date all'interno di quel decennio, incluso in qualsiasi momento il 31 dicembre 1999, puoi utilizzare:
WHERE date_col >= DATE '1990-01-01' AND date_col < DATE '2000-01-01'
Per i timestamp puoi utilizzare TO_TIMESTAMP()
o un valore letterale di timestamp:
WHERE ts_col >= TIMESTAMP '1990-01-01 00:00:00'
AND ts_col < TIMESTAMP '2000-01-01 00:00:00'
Per i timestamp con fuso orario puoi utilizzare TO_TIMESTAMP_TZ()
o un valore letterale di timestamp, con una regione del fuso orario dei nomi:
WHERE tstz_col >= TIMESTAMP '1990-01-01 00:00:00 America/New_York'
AND tstz_col < TIMESTAMP '2000-01-01 00:00:00 America/New_York'