Di seguito è riportato un elenco contenente i tipi di dati di SQL Server, in ordine di precedenza.
- Tipi di dati definiti dall'utente (massimo)
sql_variant
xml
datetimeoffset
datetime2
datetime
smalldatetime
date
time
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
image
timestamp
uniqueidentifier
nvarchar
(inclusonvarchar(max)
)nchar
varchar
(inclusovarchar(max)
)char
varbinary
(inclusovarbinary(max)
)binary
(il più basso)
Quando utilizzi un operatore per combinare operandi di diversi tipi di dati, il tipo di dati con la precedenza più bassa viene prima convertito nel tipo di dati con la precedenza più alta.
Se la conversione non è una conversione implicita supportata, viene restituito un errore.
Se entrambi gli operandi sono dello stesso tipo, non viene eseguita (o necessaria) alcuna conversione e il risultato dell'operazione utilizza il tipo di dati degli operandi.
Esempio
Ecco un esempio di conversione implicita riuscita:
SELECT 1 * 1.00;
Risultato:
1.00
Qui l'operando sinistro è stato convertito nel tipo di dati dell'operando destro.
Ecco un modo più esplicito per farlo:
DECLARE
@n1 INT,
@n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;
Risultato:
1.00
In questo caso ho dichiarato esplicitamente l'operando sinistro come INT
e l'operando destro come DECIMAL(5, 2)
.
Possiamo esaminare ulteriormente i risultati con il sys.dm_exec_describe_first_result_set
funzione di gestione dinamica del sistema.
Questa funzione ci consente di controllare il tipo di dati di ciascuna colonna restituita in una query:
SELECT
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
'DECLARE @n1 INT, @n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1, @n2, @n1 * @n2;',
null,
0);
Risultato:
+--------------------+--------------+-------------+---------+ | system_type_name | max_length | precision | scale | |--------------------+--------------+-------------+---------| | int | 4 | 10 | 0 | | decimal(5,2) | 5 | 5 | 2 | | decimal(16,2) | 9 | 16 | 2 | +--------------------+--------------+-------------+---------+
Qui possiamo vedere che ogni riga rappresenta ogni colonna restituita dalla query. Pertanto, la prima colonna era un INT
, la seconda colonna era DECIMAL(5,2)
e la terza colonna un DECIMAL(16,2)
.
Quindi SQL Server ha effettivamente restituito un DECIMAL(16,2)
, anche se il valore decimale originale era a DECIMAL(5,2)
.
Esempio di errore di conversione
Come accennato, se la conversione non è una conversione implicita supportata, viene restituito un errore:
SELECT 'Age: ' + 10;
Risultato:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Age: ' to data type int.
In questo caso, stavo cercando di concatenare una stringa (VARCHAR
) e un numero (INT
). Visto come INT
ha una precedenza maggiore di VARCHAR
, SQL Server ha tentato di convertire implicitamente la stringa in un INT
.
Questo non è riuscito, perché questa stringa non può essere convertita in un numero intero.
Per ovviare a questo, possiamo prima convertire il INT
a VARCHAR
:
SELECT 'Age: ' + CAST(10 AS VARCHAR(2));
Risultato:
Age: 10
Ora entrambi gli operandi hanno lo stesso tipo di dati, quindi SQL Server esegue correttamente l'operazione senza la necessità di eseguire conversioni implicite.
Un altro modo per eseguire questa particolare operazione è con CONCAT()
funzione:
SELECT CONCAT('Age: ', 10);
Risultato:
Age: 10
Il CONCAT()
function è una funzione di stringa e quindi converte implicitamente tutti gli argomenti in tipi di stringa prima della concatenazione. Pertanto, non era necessario che eseguissimo una conversione esplicita.
Tuttavia, se l'operando stringa può essere convertito in modo implicito in un numero, non causerà un errore quando si utilizza il +
operatore:
SELECT '10' + 10;
Risultato:
20
Ma in questo caso, il +
si trasforma in un operatore matematico di addizione, anziché in un operatore di concatenazione di stringhe.