Gestire date ed orari con SQL Server 2000

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

Print | posted on lunedì 17 gennaio 2005 21:01

Feedback

# Secondo articolo sulle Date

Left by .NET Tools Blog at 17/01/2005 21:03
Gravatar

# re: Gestire date ed orari con SQL Server 2000

Left by Davide Mauri at 25/10/2006 00:32
Gravatar Ciao Alex!

Le query

SELECT * FROM Ordini WHERE DataOrdine = CONVERT(datetime, '20050117' , 112)

e

SELECT * FROM Ordini WHERE DataOrdine = '20050117'

sono equivalenti in quanto SQL Server fa una conversione implicita.

Per quanto riguarda le altre domande (che cmq trovano gia una risposta in quanto ti ho appena detto), puoi risolvere tutti i tuoi dubbi leggendo gli articoli della serie "datetime" da qui: http://blogs.ugidotnet.org/nettools/category/806.aspx

# re: Gestire date ed orari con SQL Server 2000

Left by Davide Mauri at 25/10/2006 00:41
Gravatar Per rendere cmq l'articolo più completo ho aggiornato lo stesso con un piccolo riferimento al formato ISO da usare. Grazie per la segnalazione!

# re: Gestire date ed orari con SQL Server 2000

Left by Luciano at 31/10/2006 18:20
Gravatar ciao davide, sono alle prese con un problema che riguarda non tanto date quanto intervalli di tempo. mi spiego, ho una tabella dove ho memorizzato data inizio e data fine di un'attività. (è una tabella che viene creata importando con un dts da un file excel...)
in sql server questi dati mi vengono caricati in un campo di tipo smalldatetime. e qui nascono i problemi xchè mi mette anche la data (1900.01.01) di cui non mi interessa niente.
mi interesserebbe inoltre sapere come fare ad effettuare operazioni con gli orari (per calcolare gli intervalli di durata). ti ringrazio in anticipo.

# re: Gestire date ed orari con SQL Server 2000

Left by Davide Mauri at 21/03/2007 23:45
Gravatar @Byrollo
Ci sono diversi modi: da uno script puramente T-SQL usando la funzione RANDOM() per generare i valori anno, mese e giorno, all'utilizzo di .NET, all'utilizzo di Visual Studio Team System for Database Professionals.

# re: Gestire date ed orari con SQL Server 2000

Left by lucalolaico@tin.it at 15/11/2007 22:26
Gravatar ciao caro,
avrei bisogno di sapere di come eddettuare una query su dei database remoti collegati ad un server centrale,inoltre vorrei sapere anche come faccio ad esprimere un if not in sql....mi servirebbe per dire se questi risultati non ci sono allora fai questo.Grazie anticipatamente ciao

# re: Gestire date ed orari con SQL Server 2000

Left by Davide Mauri at 16/11/2007 16:15
Gravatar ciao lucalolaico
meglio spostare questa richiesta sul forum di UGISS:
http://community.ugiss.org/forums/10.aspx
Comments have been closed on this topic.

Copyright © Davide Mauri

Design by Bartosz Brzezinski

Design by Phil Haack Based On A Design By Bartosz Brzezinski