Vous trouverez ci-dessous une liste contenant les types de données SQL Server, par ordre de priorité.
- types de données définis par l'utilisateur (le plus élevé)
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
(y comprisnvarchar(max)
)nchar
varchar
(y comprisvarchar(max)
)char
varbinary
(y comprisvarbinary(max)
)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.