2017-07-25 8 views
1

J'ai un comportement étrange dans t-sql. Donner le test suivantComportement étrange: T-sql char/string concaténation char

DECLARE @a char(22) = 'John went to buy a car', @b char(15)= 'Tom went to pub'; 
    SELECT IIF(1=1 , @a, @b)+'. He met a friend'; 

ok sortie: John est allé acheter une voiture. Il a rencontré un ami.

SELECT IIF(1=2 , @a, @b)+'. He met a friend'; 

mal de sortie:

Tom went to pub  . He met a friend. 

La concaténation de ombles variables attribue 22 caractères si le test est vrai, et 22 caractères autrement! Ainsi, dans la concaténation de char à travers IIF (mais la même chose arrive avec CASE) la sortie est allouée pour la première expression (la variable @b est considérée comme 22 caractères!) Des idées?

Répondre

1

Un IIF est une expression et a donc besoin d'un type de données . Ce type de données ne peut pas dépendre de ce qui se passe au moment de l'exécution - il doit être connu au moment de la compilation de la requête.

Par conséquent, étant donné que les deux entrées sont un char(22) et un char(15), le type de données choisi par T-SQL pour l'expression dans son ensemble est le « plus » de ces deux, plus inclusif - à savoir, char(22) .

Donc quel que soit le résultat de l'exécution, le type du résultat sera char(22). Ce qui, comme vous l'avez observé, signifie que parfois le résultat est espacé par rapport à l'entrée choisie.


Fait intéressant, je ne trouve pas réellement ce comportement explicitement appelé nulle part dans the documentation for IIF. Il y est indiqué

Renvoie le type de données avec la plus haute priorité parmi les types dans true_value et false_value. Pour plus d'informations, consultez Data Type Precedence (Transact-SQL)

mais le linked page on Precedencene pas appeler réellement ce qui se passe pour les types de caractères de longueur fixe tels que char et varchar, à moins que je l'ai raté.

+0

Merci! C'est une excellente réponse. – user1732337