2010-06-04 4 views
4

Il s'agit plus d'une question pour satisfaire ma propre curiosité. Compte tenu de la déclaration suivante:SQL Server 2005 - Utilisation de Null dans une comparaison

DECLARE @result BIT 
SET @result = CASE WHEN NULL <> 4 THEN 0 
        ELSE 1 
       END 
PRINT @result 

Pourquoi dois-je rentrerai "1" au lieu de "0"

Changer à:

DECLARE @result BIT 
SET @result = CASE WHEN NULL IS NULL 
         OR NULL <> 4 THEN 0 
        ELSE 1 
       END 
PRINT @result 

me donne correctement les "0"

Je sais que les comparaisons NULL peuvent être difficiles, mais cet exemple particulier a échappé à notre processus de révision de code.

Toute précision seraient grandement appréciés

Répondre

9

Ceci est dû à 3 valued logic. Dans le premier cas inconnu n'évalue pas vrai si vous vous retrouvez dans l'autre

DECLARE @result BIT 
SET @result = CASE WHEN Unknown THEN 0 
        ELSE 1 
       END 
PRINT @result 

Dans le second cas, vous faites Vrai ou inconnu qui évalue à true.

DECLARE @result BIT 
SET @result = CASE WHEN True 
         OR Unknown THEN 0 
        ELSE 1 
       END 
PRINT @result 
+0

Votre code n'est pas compilé dans Management Studio. Etes-vous sûr que ce T-SQL valide (c'était une question spécifique à SQL 2005)? Je n'ai jamais vu le mot clé UNKNOWN utilisé dans T-sql. – luksan

+0

@luksan Je substituais dans les valeurs de table de vérité dans une tentative d'être utile ce n'est pas valide SQL! –

+2

Son code de pseudo. – JNappi

1

Ceci est dû à la norme ANSI SQL et au comportement des opérateurs de comparaison avec NULL. Chaque fois que vous voulez comparer une valeur avec une valeur qui pourrait être NULL, vous devez utiliser l'opérateur IS pour vérifier explicitement le cas où la valeur pourrait être NULL. Ou vous pouvez désactiver l'option ANSI_NULLS dans SQL Server.

Les exemples suivants font ce que vous voulez:

DECLARE @result BIT 
DECLARE @input INT 

SET @input = NULL 
SET @result = CASE WHEN (@input IS NULL OR @input <> 4) THEN 0 
        ELSE 1 
       END 
PRINT @result 

Ou ceci:

SET ANSI_NULLS OFF 

DECLARE @result BIT 
SET @result = CASE WHEN NULL <> 4 THEN 0 
        ELSE 1 
       END 
PRINT @result 

Références:

http://msdn.microsoft.com/en-us/library/ms188048.aspx

1

Du point de vue purement technique, la raison pour laquelle la première instruction renvoie un 1 car ANSI_NULLS est défini sur "ON" qui traite NULL comme "Inconnu" qui suit la norme ISO.

Pour que les valeurs s'évaluent comme prévu, exécutez votre script avec SET ANSI_NULLS OFF en avant.

Dans la vraie vie, bien sûr, ISNULL() est l'approche la plus impressionnante/la plus sûre.

+0

Je suis d'accord en utilisant isnull est génial mais je ne l'appellerais pas "sûr". Vous devez connaître vos types de données sous-jacents et leurs longueurs, ce qui réduit considérablement le nombre de ses inquiétudes. C'est à dire, quand isnull (A.Field, 'ceci est une valeur nulle') = isnull (B.Field, 'ceci est une valeur nulle') alors 1' ne retournera pas 1 si A.Field est varchar (4) et B.Field est varchar (10). Mais si vous choisissez une valeur alternative minimale, vous devrez peut-être vous soucier de savoir si elle correspond accidentellement à une valeur réelle dans vos tables. – Matt

Questions connexes