Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Precedenza del tipo di dati in SQL Server

Di seguito è riportato un elenco contenente i tipi di dati di SQL Server, in ordine di precedenza.

  1. Tipi di dati definiti dall'utente (massimo)
  2. sql_variant
  3. xml
  4. datetimeoffset
  5. datetime2
  6. datetime
  7. smalldatetime
  8. date
  9. time
  10. float
  11. real
  12. decimal
  13. money
  14. smallmoney
  15. bigint
  16. int
  17. smallint
  18. tinyint
  19. bit
  20. ntext
  21. text
  22. image
  23. timestamp
  24. uniqueidentifier
  25. nvarchar (incluso nvarchar(max) )
  26. nchar
  27. varchar (incluso varchar(max) )
  28. char
  29. varbinary (incluso varbinary(max) )
  30. 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.