Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Lavorare con il campo data in SQL Server

Come utilizzare al meglio i formati Datetime e Smalldatetime.
Come utilizzare al meglio i formati Datetime e Smalldatetime.
Link copiato negli appunti

Sql Server non possiede tipi dati separati per archiviare i valori di data e ora. Adotta una strategia differente: un tipo dati combinato, denominato datetime, in grado di archiviarli entrambi.

La suddivisione tra Datetime e Smalldatetime

I tipi datetime sono suddivi in due tipologie:

  1. Datetime.
    Ammette valori compresi tra il 1 Gennaio 1753  31 Dicembre 9999 8 byte precisione al trecentesimo di secondo
  2. Smalldatetime.
    Ammette valori compresi tra il 1 Gennaio 1900 6 Giugno 2079 4 byte una precisione al minuto

I valori datetime archiviano data e ora con grande precisione, per questo motivo utilizzano 8 byte per la memorizzazione:

  • 4 byte per il numero di giorni precedenti o successivi alla data di base,
    ovvero il 1° gennaio 1900
  • 4 byte per l'ora del giorno, espressa come numero di millisecondi dopo la
    mezzanotte

Al contrario i valori smalldatetime

  • 2 byte per il numero di giorni successivi al 1° gennaio 1900
  • 2 byte per il numero di minuti dopo la mezzanotte

Inoltre per valori smalldatetime

SQL: date rifiutate

I valori non riconosciuti in SQL Server come date comprese tra il 1753 e il
9999 vengono rifiutati, vediamo alcuni esempi di valori non corretti:

Ogni volta che tentiamo di inserire una data non valida, SQL Server ci invia
il seguente messaggio:

Inserire valori di data e tempo in SQL Server

Nel paragrafo precedente, abbiamo visto che l'immissione di date in SQL Server avviene tramite stringhe costanti le quali vengono interpretate e convertite in formato binario.

Una volta che i dati relativi a data e ora sono rappresentati in formato binario, l'esecuzione dei calcoli complessi su date e ore risulta semplice, così come la conversione delle date e delle ore in stringhe durante l'applicazione di formati diversi mediante le funzioni T-SQL.

Il fatto di inserire le date sotto forma di stringhe, implica che le impostazioni di localizzazione di SQL Server influenzino le operazioni di inserimento delle date, vediamo un esempio:


Go
DECLARE @DATA DATETIME
SELECT @DATA = '03/08/04'

Il valore selezionato sarà il 20 Marzo 2004 o 3 Agosto 2004? Come fa SQL Server a capire quale data vogliamo memorizzare? Proviamo a vedere come interpreta la data '03/08/2004'

SELECT @DATA, CONVERT(VARCHAR(20), @DATA)

Sul mio SQL Server il risultato è:

2004-03-08 00:00:00.000    Mar  8 2004 12:00AM

Nel mio caso SQL Server memorizza la data come 8 Marzo 2004, dato che le impostazioni di localizzazione del mio Server Sql sono settate sull' Inglese Americano e quindi il formato data atteso durante l'inserimento è Mese-Giorno-Anno

È ovvio che le impostazione della lingua localizzazione

Ovviamente tutte le impostazioni di localizzazione possono essere modificate
sia a livello di connessione che di sessione tramite apposiste comandi T-SQL.

Le lingue e le impostazioni di localizzazione

In SQL Server è presente un concetto di lingua distinto e separato rispetto
al concetto di impostazioni internazionali di Windows (visibili e configurabili
da pannello di controllo).

Per questo motivo è bene definire un'impostazione della lingua specifica di
SQL Server come langid anziché come lingua o impostazione internazionale.

Un langid consente a SQL Server di stabilire in che modo devono essere eseguite alcune operazioni relative a data e ora, valori monetari e messaggi di sistema. Ogni volta che un utente stabilisce una connessione a SQL Server,  esso controlla che esista un langid valido per la connessione, in caso contrario viene assegnato il langid predefinito. I langid di SQL Server e le relative impostazioni sono memorizzati nella tabella syslanguages sulla quale è possibile eseguire interrogazioni utilizzando la procedura memorizzata sp_helplanguage.

Il set di risultati restituiti è il seguente:

Nome
colonna

Tipo
di dati

Descrizione

langid smallint Numero di identificazione della
lingua
dateformat nchar(3) Formato della data
datefirst tinyint Primo giorno della settimana: 1
per lunedì, 2 per martedì e così via fino a 7 per domenica
upgrade int Versione dell'ultimo aggiornamento
di SQL Server per la lingua specificata
name sysname Nome della lingua
alias sysname Nome alternativo per la lingua
months nvarchar(372) Nomi dei mesi
shortmonths nvarchar(132) Nomi dei mesi abbreviati
days nvarchar(217) Nomi dei giorni
lcid int ID delle impostazioni internazionali
di Microsoft Windows NT® relative alla lingua specificata
msglangid smallint ID del gruppo di messaggi di SQL
Server

Per provare a vedere il contenuto della tabella eseguite nel QA questa istruzione EXEC sp_ helplanguage.

L'unica eccezione è rappresentata dal langid 0 (us_english) syslanguages

Nel prima parte dell'articolo abbiamo introdotto il tipo dati datetime di SQL Server ed analizzato l'influenza delle impostazioni di localizzazione sulle operazioni di inserimento e calcolo con i valori datetime. Ora invece vedremo come effettuare le operazioni di formattazione, conversione e ricerca sui campi data.

Funzioni per la conversione di valori datetime

Il linguaggio T-SQL adotta due funzioni in grado di effettuare la conversione
tra tipi dati differenti: CAST e CONVERT. In particolar modo la funzione CONVERT offre un'ampia gamma di stili di conversione. La sintassi della funzione CONVERT è la seguente:


] )
--Converte la data corrente nel formato Italiano
SELECT CONVERT( VARCHAR, GETDATE(), 105 )
--Restituisce
07-02-2005

Uno stralcio degli stili disponibili per l'utilizzo con la funzione CONVERT

Senza
secolo (yy)

Con
secolo (yyyy)

Standard

Input/Output
- 0 or 100 (*) Default mon dd yyyy hh:miAM
(or PM)
1 101 USA mm/dd/yy
2 102 ANSI yy.mm.dd
3 103 British/French dd/mm/yy
4 104 German dd.mm.yy
5 105 Italian dd-mm-yy
6 106 - dd mon yy
7 107 - Mon dd, yy
8 108 - hh:mm:ss
- 9 or 109 (*) Default + milliseconds mon dd yyyy hh:mi:ss:mmmAM
(or PM)
10 110 USA mm-dd-yy
11 111 JAPAN yy/mm/dd
12 112 ISO yymmdd

NB:

I valori in tabella rappresentano sia i formati di input formati di output

La cosa importante da ricordare è che SQL Server restituisce al client i valori datetime solo come stringhe di caratteri.

Vediamo ora alcuni esempi di utilizzo della funzione CONVERT:

Funzioni per manipolare i valori datetime

Prima di passare in rassegna le funzioni per la manipolazione delle date è
bene comprendere il concetto di "parti di data".

Esse definiscono unità discrete di tempo che possono essere estratte da un valore datetime o utilizzate in calcoli datetime. In SQL Server ne esistono diverse e identificano intervalli temporali compresi tra un millisecondo e un secolo. Ecco l'elenco completo:

  1. yy
  2. qq
  3. mm
  4. dy
  5. dd
  6. wk
  7. dw
  8. hh
  9. mi, n
  10. 10.  ss, s
  11. ms

È bene ricordare che la parte di data riguardante la settimana (wk, ww) riflette le modifiche apportate mediante la funzione SET DATEFIRST ed inoltre che il 1° gennaio di ogni anno definisce il numero iniziale della parte di data settimana. Anche la parte di data giorno della settimana (dw con valori da 1 a 7) dipende dal valore impostato con la funzione SET DATEFIRST, che consente di impostare il primo giorno della settimana.

SQL Date: tutte le funzioni

Vediamo ora l'elenco delle principali funzioni per manipolare le date:

  1. Dateadd
    dell'intervallo aggiunto alla data specificata.
    Sintassi
  2. Datediff
    al numero di intervalli di tempo tra due valori Date.
    Sintassi
  3. Datename
    Syntax
  4. Datepart
    di data di una specifica data.
    Sintassi
  5. Day
    di una specifica data.
    Sintassi
  6. Getdate
    memorizzazione interna di SQL Server, è la data di sistema.
    Sintassi
  7. Month
    di una specifica data.
    Sintassi
  8. Year
    di una specifica data.
    Sintassi

SQL Date: tutti gli esempi delle funzioni

Ecco alcuni esempi di utilizzo di queste funzioni:

Ricerca all'interno di campi datetime

Nella maggioranza delle applicazioni la ricerca su campi data diventa diventa
fondamentale. Possiamo avere svariate tipologie di ricerca sui campi data, anche
se le principali sono:

  1. Per range di data
  2. Per data esatta

Per provare i vari casi elencati creiamo una tabella ad hoc su cui testare
gli esempi che svilupperemo. Vi consiglio inoltre di usare questa tabella per
provare le vostre query in un ambiente di prova per non avere sorprese sgradevoli al momento di mettere in produzione il codice T-SQL! Vediamo il codice:

Ricerca per range di data

Supponiamo di voler cercare tutte le date del mese di Febbraio 2003 per la
tabella T_PROVA, il risultato atteso è di 28 righe. Per sviluppare la query è
consigliato l'operatore BETWEEN:

I risultati sono tutti corretti, ma sono dipendenti (tranne l'ultimo caso)
dalle impostazioni del linguaggio (in questo caso usiamo SET
DATEFORMAT per informare SQL Server sul formato di input della data). Quindi
prima di valutare query simili dobbiamo sempre tenere in considerazione il linguaggio con cui la nostra login, connessione o sessione di SQL Server è impostata.

Ricerca per data esatta

È sicuramente una delle ricerche più comuni e banali ma nasconde alcune insidie. Proviamo a creare una query capace di restituire la riga corrispondente alla data corrente nella tabella T_PROVA generata precedentemente:

Apparentemente semplice, ma il risultato non è scontato! La query non restituisce alcuna riga, eppure tutto è corretto perché la data odierna è sicuramente presente nella tabella.

Anche se ciò è vero non ci sono risultati perché i valori che andiamo a confrontare non sono uguali, o meglio solo in parte.

La data memorizzata nella tabella (al momento in cui ho eseguito lo script
ovviamente) è pari a '2005-02-07 22:03:39.117' mentre la funzione GETDATE() restituisce solamente la stessa parte di data con un tempo in ore minuti e millisecondi logicamente differente.

Per fare un confronto omogeneo dobbiamo eliminare la porzione ore, minuti e millisecondi da entrambe le date

--1

SELECT * FROM T_PROVA WHERE DATEDIFF(DD, DATA, GETDATE()) = 0

--2

SELECT * FROM T_PROVA WHERE FLOOR( CAST(DATA
AS FLOAT) ) = FLOOR( CAST(GETDATE() AS FLOAT) )

--3

SELECT * FROM T_PROVA WHERE CONVERT(VARCHAR(8),DATA,112)
= CONVERT(VARCHAR(8),GETDATE(),112)

--4

SELECT * FROM T_PROVA WHERE YEAR(DATA) = 2005
AND MONTH(DATA) = 2 AND DAY(DATA)=7

--5

DECLARE @D INT

-- Estrapola solo la parte della data come numero intero

-- grazie alla funzione FLOOR, faccio il CAST di GETDATE() a FLOAT

SET @D = FLOOR( CAST(GETDATE() AS FLOAT) )

SELECT * FROM T_PROVA WHERE DATA BETWEEN @D AND
@D + 1

Screenshot

Nel caso n. 5 grazie all'operatore BETWEEN possiamo anche sfruttare un eventuale indice piazzato nella colonna DATA e rendere ancora più performante la ricerca.

Conclusione SQL Server - date

Nell'articolo abbiamo esaminato le insidie nascoste all'interno dei valori datetime ed inoltre imparato a conoscere l'importanza delle impostazione di localizzazione di SQL Server nelle operazioni di calcolo e inserimento delle date. Infine abbiamo descritto le funzioni di conversione e formattazione delle date condensando il tutto nelle query di ricerca sui campi datetime.

Ti consigliamo anche