Per chiudere il cerchio sull'argomento "Date e SQL Server" è bene, anzi è obbligatorio, parlare anche degli orari. Non è un caso che il tipo di dato si chiami datetime. Come detto in precedenza, SQL Server non è in grado di memorizzare una data senza appiccicarci anche l'orario.
Questo significa che se si specifica una data senza un orario, SQL Server mette quello di default, ossia 00:00:00.000; per questo motivo il confronto fra date può sembrare difficoltoso.
Una query molto semplice come
SELECT * FROM Ordini WHERE DataOrdine = '20050117'
può diventare foriera di dubbi e problemi. Gli unici ordini restituiti da questa query, infatti, saranno gli ordini fatti esattamente a mezzanotte...che probabilmente non saranno poi molti, se, quando abbiamo immeso l'ordine, abbiamo semplicemente specificato un banalissimo GETDATE() (Questo comando restituisce la data corrente, ora compresa. Il suo reciproco in .NET è DateTime.Now).
Se non ci serve la parte relativa all'ora è bene eliminarla. Come?
Semplice:
SELECT CONVERT(CHAR(8), GETDATE(), 112)
La query di esempio sopra riportata, quindi, dovrebbe diventare:
SELECT * FROM Ordini WHERE CONVERT(CHAR(8), DataOrdine , 112) = '20050117'
Che funziona anche bene, ma non è certo il massimo dal punto di vista delle prestazioni, in quanto inibisce l'uso degli indici. Meglio essere più furbi allora e utilizzare due soluzioni:
1) Se l'ora non ci serve non memorizziamola, mettiamo solo la data, cosi che l'ora sia sempre 00:00:00.000
2) Se l'ora invece l'abbiamo memorizzata la nostra query può essere riscritta in questo modo:
SELECT * FROM Ordini WHERE DataOrdine BETWEEN '20050117 00:00:00.000' AND '20050117 23:59:59.997'
Occhio all'orario finale! I millesimi di secondo non sono 997 a caso, ma sono l'ultimo valore utile per SQL Server. SQL Server, infatti, è in grado di memorizzare le date con una precisione di 3 millesimi di secondo. Se avessi messo 998 o 999, la data sarebbe diventata 20050118, procucendo quindi risultati sbagliati.
Un'ultima cosa riguarda la gestione del solo orario: l'operatore CONVERT permette anche di ottenere, da un valore datetime, solo l'ora, utilizzando un diverso codice per il parametro "style" (l'ultimo). Ad esempio:
SELECT CONVERT(CHAR(12), GETDATE(), 114)
restituisce l'orario in questo formato:
hh:mm:ss.mmm
Per tutta la lista dei possibili valori di style, fare riferimento qui:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ca-co_2f3o.asp
E con questo ho detto tutto! (Almeno tutto ciò che a livello pratico serve!)
Dato che ho visto che c'è stato un buon interesse per l'articolo precedente (circa 50 view in meno di 3 ore), se ci sono altri argomenti che interessano lasciate un commento, e, a seconda dell'interesse, scriverò altri articoli su SQL Server.
Update del 24 ottobre 2006
Tirando le somme, quindi, nel caso in cui si voglia specificare una data ed un'ora che siano sempre comprese correttamente da SQL Server (senza quindi avere problemi dovuti alla localizzazione del formato) è bene specificarla così:
YYYYMMDD hh:mm:ss.nnn
oppure, se si vogliono separare le cifre della data
YYYY-MM-DDThh:mm:ss.nnn
per informazioni più approfondite su come SQL Server tratta i formati ISO delle date, leggete questo articolo: http://blogs.ugidotnet.org/nettools/articles/40144.aspx