I tipi di dato in SQL server

5
(1)

In questa pagina è riportata una panoramica di tutti i tipi disponibili in SQL server.

Dati testuali

char, nchar, varchar, nvarchar

I tipi di dato *char contengono stringhe composte da caratteri.

Per i tipi carattere è necessario specificare sempre la lunghezza, per esempio un campo varchar(50) contiene stringhe di testo lunghe al massimo 50 caratteri.

Cosa significa la “n”? La rappresentazione dei caratteri usa 1 byte per char e varchar, 2 byte per nchar e nvarchar. Per questo i tipi nchar e nvarchar permettono di memorizzare caratteri cinesi, arabi, hindi e molti altri. In realtà il discorso è un po’ più complicato, perché dipende dalla collation utilizzata.

Che differenza c’è tra char e varchar? I campi di tipo char usano lo spazio come riempitivo per raggiungere la lunghezza massima, mentre i campi varchar usano un numero di byte pari allo spazio effettivamente utilizzato.

Qual è la lunghezza massima di un campo varchar? E di un nvarchar? La lunghezza di un campo varchar va da 1 a 8000, mentre quella di un nvarchar da 1 a 4000. È comunque possibile usare come lunghezza la parola chiave max (es: varchar(max)), che memorizza la stringa di testo “out of row”, cioè in uno spazio che fisicamente non fa parte del record. In questo caso il limite è di circa 2 miliardi di caratteri (2.147.483.648), ma se si usa max la colonna non può far parte di un indice (errore 1919).

text, ntext

I tipi di dato text e ntext sono equivalenti a varchar(max) e nvarchar(max). Microsoft raccomanda di non usare questi tipi di dato, perché saranno rimossi dalle versioni più recenti di SQL Server.

sysname

Un sinonimo di nvarchar(128) con un vincolo NOT NULL. Usato prevalentemente dal database per memorizzare nomi di oggetti.

Dati numerici

I dati numerici si possono dividere in tre grandi famiglie

  • i numeri interi, veloci da processare (es. 1, -47, 5.000)
  • i numeri decimali, in cui la parte intera e quella decimale sono fisse (es. € 12,30, 50,320, $ 300,00)
  • i numeri in cui in base alle cifre decimali si decide dove posizionare il separatore dei decimali

Dal punto di vista delle prestazioni, i numeri decimali non sono molto diversi dagli interi: per fare un esempio, se contassimo i soldi non in euro, ma in centesimi, il calcolo sarebbe tra numeri interi.

ATTENZIONE: nel mondo anglosassone il separatore delle migliaia e quello dei decimali sono invertiti rispetto alla lingua italiana. Per esempio, nei giornali americani si potrebbe leggere $ 3,000.00 (virgola per le migliaia, punto per i decimali), mentre in quelli italiani € 3.000,00 (punto per le migliaia, virgola per i decimali).

Da qui anche la differenza tra l’italiano “numeri in virgola mobile” e l’inglese “floating point numbers”.

bit, tinyint, smallint, int, bigint

L’unica differenza tra queste cinque rappresentazioni dei numeri interi è la dimensione massima rappresentabile, oltre al fatto che bit e tinyint non possono rappresentare numeri negativi.

TipoByteLimiti
bit1 bit
1/8 di byte
da 0 a 1
tinyint1da 0 a 255
smallint2da -32.768 a 32.767
int4da -2 miliardi a + 2 miliardi (circa):
da -2.147.483.648 a 2.147.483.647
bigint8da -9 miliardi di miliardi a
+ 9 miliardi di miliardi (circa):
da -9.223.372.036.854.775.808 a
9.223.372.036.854.775.807

decimal o numeric, smallmoney, money

decimal e numeric sono sinonimi in SQL server. Sono dati in cui sono specificate la precisione (il numero di cifre) e la scala (il numero di decimali); la dimensione include i decimali.

Per esempio, dichiarare una variabile di tipo decimal(8, 3) significa dichiarare che la variabile contiene un numero composto al massimo da otto cifre di cui 5 per la parte intera e 3 per la parte decimale. 15.384,308 è un esempio di numero di 8 cifre totali di cui 3 decimali.

Dimensione: 8 (la virgola non è considerata)
3 decimali
15384,308

money e smallmoney sono i tipi di dato ideali per rappresentare soldi: sono molto simili a decimal, con una precisione e una scala predefiniti.

float, real

I dati di tipo float e real determinano la precisione in base al numero che devono memorizzare: in modo simile alla notazione scientifica, una parte dell’informazione è il numero vero e proprio e una parte rappresenta lo spostamento della virgola.

Dati temporali

date, datetime, datetime2, smalldatetime, time

Date permette di memorizzare la sola data, Time il solo tempo, Smalldatetime data e ora (fino al 06/06/2079), Datetime data e ora (con millisecondi) e Datetime2 data e ora (con microsecondi).

Per aggiungere o togliere giorni è possibile usare anche gli operatori + e – e i numeri interi (es. select cast('1976-01-11' as datetime) + 1 restituirà 12/01/1976; ), mentre per operazioni più complesse, come aggiungere o togliere ore, oppure calcolare la differenza in mesi, si possono usare le funzioni di data come DATEADD o DATEDIFF

datetimeoffset

Datetimeoffset memorizza, oltre alla data e all’ora, anche il fuso orario. In questo modo è possibile interrogare un database utilizzando il fuso orario di sistema per ottenere un’ora sincronizzata con il proprio fuso.

Per esempio SELECT CAST('1976-01-11 10:30:00' as datetimeoffset) AT TIME ZONE 'Hawaiian Standard Time' restituisce 1976-01-11 00:30:00.0000000 -10:00, perché quando qui erano le 10:30, alle Hawaii erano le 00:30.

dati binari

binary, varbinary, image

I dati di tipo binario contengono informazioni espresse come sequenza di byte, per esempio file audio, immagini, documenti eccetera.

Il tipo binary contiene elementi della stessa dimensione, mentre il tipo varbinary utilizza il numero minimo di byte in base al valore, come char e varchar.

Il tipo di dato image sarà rimosso dalle future versioni di SQL server, quindi ne è scoraggiato l’utilizzo.

uniqueidentifier

Un GUID è una sequenza esadecimale di cui SQL server garantisce l’unicità. In altre parole, quando si richiama la funzione NEWID(), questa restituisce un dato ogni volta diverso. Un campo uniqueidentifier è adatto a contenere un GUID.

sql_variant

Il tipo “jolly” di SQL server, che per poter usare come un altro tipo va convertito esplicitamente. In un campo sql_variant si può inserire qualunque cosa stia sotto gli 8000 byte, quindi si presta per valori di tipo eterogeneo (non è una buona idea!) ma di solito è usato come output per la funzione sql_variant_property, che restituisce informazioni come la lunghezza o la collation di una variabile.

Tipi di dato con metodi

geometry e geography

I tipi di dato geometry e geography sono utilizzati per effettuare query di tipo geometrico (per esempio, si dichiarano due aree e si cerca qual è la loro intersezione).

I dati geometry rappresentano punti, linee e superfici su geometria piana (come quella di un tavolo), mentre i dati geography rappresentano elementi su una geometria sferica (come la superficie della Terra).

geometry e geography sono tipi che implementano metodi, quindi è possibile dichiarare una variabile di questi tipi e poi usare su quella variabile dei metodi, per esempio per capire se due forme sono uguali.

hierarchyid

I dati hierarchyid servono a rappresentare dati ordinati in maniera gerarchica, per esempio un albero binario.

Rispetto alla rappresentazione tramite ID interni (ID che si riferiscono ad altri elementi della stessa tabella), hierarchyid garantisce prestazioni migliori nelle ricerche e nell’inserimento.

Implementa alcuni metodi che permettono di trovare, ad esempio, l’elemento origine, il padre e il fratello.

xml

Il tipo di dato xml contiene stringhe di codice XML well formed e interrogabile tramite i metodi implemetati dal tipo.

Un campo di tipo XML può essere trasformato in una tabella e viceversa.

Un campo XML può anche essere interrogato con una query xpath.

Altre considerazioni

Valori NULL

Tutti i tipi supportano il valore NULL, che significa che il valore è vuoto.

Un valore NULL non va verificato con = (uguale), perché l’uguaglianza si ha tra due valori, mentre NULL non lo è. Per verificare se un campo è NULL o no, bisogna usare IS:

SELECT * FROM table WHERE value IS NULL

Un valore NULL incluso in una somma restituirà un risultato NULL:

SELECT 5 + 6 + NULL -- risultato NULL

INSERT INTO table1 (value1) values (1)
INSERT INTO table1 (value1) values (2)
INSERT INTO table1 (value1) values (NULL)
SELECT SUM(value1) -- risultato NULL

Un campo che fa parte di una chiave primaria non può avere valori NULL.

Conversione di dati

I valori in SQL server possono essere convertiti di tipo tramite i comandi CAST e CONVERT.

Non tutti i dati possono essere convertiti direttamente, o perché non sono rilevabili (es. il testo 3,1415 potrebbe non essere interpretato correttamente perché ha una virgola) oppure perché non sono corretti (es. il testo “ciao!” non ha un significato numerico).

La seguente tabella mostra quali tipi possono essere convertiti in altri tipi (tratto da https://docs.microsoft.com/it-it/sql/t-sql/functions/cast-and-convert-transact-sql)

Tabella di conversione dei tipi
Tabella di conversione dei tipi

Concatenamento di valori di tipo diverso

In SQL server NON è possibile concatenare tipi di testo con altri tipi senza una conversione. Non è possibile quindi scrivere qualcosa come

declare @c varchar(20), @i int
select @c = 'coccodrilli: ', @i = 2
print @c + @i

perché restituirebbe un errore 245: Conversione non riuscita durante la conversione del valore varchar ‘coccodrilli: ‘ nel tipo di dati int.

La stringa corretta è:

declare @c varchar(20), @i int
select @c = 'coccodrilli: ', @i = 2
print @c + cast(@i as varchar(1))

Il risultato è:

coccodrilli: 2

Collation

La collation è associata ai tipi testo e ne rappresenta le regole di confronto.

Per esempio, queste tre stringhe sono uguali?

ciao
CIAO
Ciao

e queste?

sì, però...
si, pero...

La collation specifica se il confronto tra due stringhe deve tenere conto del case (maiuscole/minuscole), delle lettere accentate e di altre impostazioni “avanzate”.

Un esempio di collation – comune in Italia – è Latin1_General_CI_AS, dove CI significa “Case Insensitive”, cioè non c’è differenza tra maiuscole e minuscole, e AS significa “Accent Sensitive”, quindi una parola con l’accento è considerata diversa da una parola senza (es. sì [avverbio], si [pronome o nota musicale])

[askmeanythingpeople anonymous_name=”Anonimo” success_text=”La tua richiesta è stata inoltrata.” question_box_title=”La tua domanda” placeholder=”Siccome le domande e le risposte potrebbero essere pubblicate, per piacere non lasciare dati personali in questo modulo.” test_question=”Quanto fa tre per otto (in cifre)?” test_answer=”24″ ask_button_text=”Richiedi” answer_list_title=”Domande” no_answers_text=”” avatar=”wavatar”]

Hai trovato utile questo contenuto?

Valutazione: 5 / 5. Voti: 1

Vota per primo questo contenuto

Ci dispiace che tu abbia trovato inutile o sbagliato questo contenuto

Lasciaci un messaggio

Come possiamo migliorare?

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Moderazione dei commenti attiva. Il tuo commento non apparirà immediatamente.