Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Priorité des types de données dans SQL Server

Vous trouverez ci-dessous une liste contenant les types de données SQL Server, par ordre de priorité.

  1. types de données définis par l'utilisateur (le plus élevé)
  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 (y compris nvarchar(max) )
  26. nchar
  27. varchar (y compris varchar(max) )
  28. char
  29. varbinary (y compris varbinary(max) )
  30. binary (le plus bas)

Lorsque vous utilisez un opérateur pour combiner des opérandes de différents types de données, le type de données avec la priorité la plus faible est d'abord converti en type de données avec la priorité la plus élevée.

Si la conversion n'est pas une conversion implicite prise en charge, une erreur est renvoyée.

Si les deux opérandes sont du même type, aucune conversion n'est effectuée (ou nécessaire) et le résultat de l'opération utilise le type de données des opérandes.

Exemple

Voici un exemple de conversion implicite réussie :

SELECT 1 * 1.00;

Résultat :

1.00

Ici, l'opérande de gauche a été converti dans le type de données de l'opérande de droite.

Voici une manière plus explicite de procéder :

DECLARE 
    @n1 INT, 
    @n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;

Résultat :

1.00

Dans ce cas, j'ai explicitement déclaré l'opérande gauche comme un INT et l'opérande de droite sous la forme DECIMAL(5, 2) .

Nous pouvons examiner plus en détail les résultats avec le sys.dm_exec_describe_first_result_set fonction de gestion dynamique du système.

Cette fonction nous permet de vérifier le type de données de chaque colonne renvoyée dans une requête :

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);

Résultat :

+--------------------+--------------+-------------+---------+
| system_type_name   | max_length   | precision   | scale   |
|--------------------+--------------+-------------+---------|
| int                | 4            | 10          | 0       |
| decimal(5,2)       | 5            | 5           | 2       |
| decimal(16,2)      | 9            | 16          | 2       |
+--------------------+--------------+-------------+---------+

Ici, nous pouvons voir que chaque ligne représente chaque colonne renvoyée par la requête. Par conséquent, la première colonne était un INT , la deuxième colonne était DECIMAL(5,2) , et la troisième colonne un DECIMAL(16,2) .

Donc, SQL Server a en fait renvoyé un DECIMAL(16,2) , même si la valeur décimale d'origine était un DECIMAL(5,2) .

Exemple d'erreur de conversion

Comme mentionné, si la conversion n'est pas une conversion implicite prise en charge, une erreur est renvoyée :

SELECT 'Age: ' + 10;

Résultat :

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Age: ' to data type int.

Dans ce cas, j'essayais de concaténer une chaîne (VARCHAR ) et un nombre (INT ). Vu comme INT a une priorité plus élevée que VARCHAR , SQL Server a tenté de convertir implicitement la chaîne en un INT .

Cela a échoué, car cette chaîne ne peut pas être convertie en entier.

Pour surmonter cela, nous pouvons d'abord convertir le INT en VARCHAR :

SELECT 'Age: ' + CAST(10 AS VARCHAR(2));

Résultat :

Age: 10

Maintenant, les deux opérandes ont le même type de données, et donc SQL Server exécute l'opération avec succès sans avoir besoin d'effectuer de conversions implicites.

Une autre façon de faire cette opération particulière est avec le CONCAT() fonction :

SELECT CONCAT('Age: ', 10);

Résultat :

Age: 10

Le CONCAT() La fonction est une fonction de chaîne et convertit donc implicitement tous les arguments en types de chaîne avant la concaténation. Par conséquent, nous n'avons pas eu besoin d'effectuer une conversion explicite.

Cependant, si l'opérande de chaîne peut être implicitement converti en nombre, cela ne provoquera pas d'erreur lors de l'utilisation de + opérateur :

SELECT '10' + 10;

Résultat :

20

Mais dans ce cas, le + se transforme en un opérateur mathématique d'addition, plutôt qu'en un opérateur de concaténation de chaînes.