Conversions de type de données ISNULL et implicite dans TSQL

J'ai rencontré un comportement un peu bizarre avec les conversions de type de données lors de l'utilisation de ISNULL. Regarde ça:

PRINT CASE WHEN ISNULL('', 0) = 0 THEN 'true' ELSE 'false' END PRINT CASE WHEN ISNULL('', 0) = '' THEN 'true' ELSE 'false' END PRINT CASE WHEN ISNULL(NULL, 0) = '' THEN 'true' ELSE 'false' END 

Toutes ces expressions sont vraies. Mais quand je déclare une variable nvarchar et la place à NULL, ce qui suit arrive:

 DECLARE @charType nvarchar; SET @charType = NULL; PRINT CASE WHEN ISNULL(@charType, 0) = '' THEN 'true' ELSE 'false' END 

Cela devrait également être vrai, mais il est faux. Pourquoi?

Ici ISNULL('', 0) renvoie '' et ISNULL(NULL, 0) renvoie 0

Data Type Precedence

Lorsqu'un opérateur combine deux expressions de types de données différents, les règles de priorité de type de données spécifient que le type de données de priorité inférieure est 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.

Comme int plus de Precedence sur char , '' sera converti en int .

 select cast('' as int) ==> 0 

Par conséquent, dans le premier cas, tous les '' seront convertis en 0 , donc la requête sera réduite à

 PRINT CASE WHEN 0 = 0 THEN 'true' ELSE 'false' END PRINT CASE WHEN '' = '' THEN 'true' ELSE 'false' END PRINT CASE WHEN 0 = 0 THEN 'true' ELSE 'false' END 

D'où il imprime true

ISNULL

Renvoie le même type que check_expression. Si une valeur NULL littérale est fournie en tant que check_expression, renvoie le type de données de la valeur de rlocation. Si une valeur NULL littérale est fournie en tant que check_expression et qu'aucune valeur de rlocation n'est fournie, renvoie une valeur int

Mais dans le second cas, car @charType est null , ISNULL va lancer la valeur 0 à nvarchar puis la requête devient

Alors

 PRINT CASE WHEN '0' = '' THEN 'true' ELSE 'false' END 

D'où il imprime false

Essaye ça:

 PRINT CASE WHEN CAST(ISNULL('', 0) AS nvarchar) = 0 THEN 'true' ELSE 'false' END PRINT CASE WHEN CAST(ISNULL('', 0) AS nvarchar) = '' THEN 'true' ELSE 'false' END PRINT CASE WHEN CAST(ISNULL(NULL, 0) AS nvarchar) = '' THEN 'true' ELSE 'false' END 

Comme vous pouvez le voir, SQL sait qu'il doit convertir en nvarchar lorsque @charType est défini sur un type nvarchar.

Qu'essayez-vous d'accomplir?