NOT
est toujours une négation. La raison de ce comportement de T-SQL se trouve dans le fait qu' null
des valeurs sont traités de manière spécifique en fonction d'une base de données de configuration (connu sous le nom ansi_nulls
). En fonction de ce paramètre, null
sont traitées de la même manière que toute autre valeur ou il est traité comme "valeur non définie". Dans ce cas, toutes les expressions contenant des valeurs null sont considérées comme non valides.
En outre, l'expression
(@a IS NULL AND @b IS NULL)
OR
@a = @b
ne vise que le cas lorsque les deux variables sont NULL
, il ne traite pas de cas lorsque @a
ou @b
est NULL
. Si cela se produit, le résultat dépend de la valeur de ansi_nulls
: si c'est on
, alors le résultat de l' @a = @b
toujours false
si l'une des variables est - NULL
.
Si ansi_nulls
est off
, alors NULL
est traitée comme une valeur et se comporte comme prévu.
Pour éviter de tels comportements inattendus, vous devez couvrir tous les cas, comme suit:
DECLARE
@a VARCHAR(10) = 'a',
@b VARCHAR(10) = null
SELECT
CASE
WHEN (@a IS NOT null AND @b IS null) THEN 0
WHEN (@a IS null AND @b IS NOT null) THEN 0
WHEN (@a IS null AND @b IS null) THEN 1
WHEN (@a=@b) THEN 1
ELSE 0
END
Notez que dans cet exemple, tous les null cas sont traités avant que l' @a=@b
de cas est vérifié (en CASE
- déclaration, l' WHEN
s'sont traitées dans l'ordre où elles apparaissent, et si une condition est satisfaite, le traitement est terminé et que la valeur spécifiée est retourné).
Pour tester tous les possibles (pertinent) des combinaisons, vous pouvez utiliser ce script:
DECLARE @combinations TABLE (
a VARCHAR(10),b VARCHAR(10)
)
INSERT INTO @combinations
SELECT 'a', null
UNION SELECT null, 'b'
UNION SELECT 'a', 'b'
UNION SELECT null, null
UNION SELECT 'a', 'a'
SELECT a, b,
CASE
WHEN (a IS NOT null AND b IS null) THEN 0
WHEN (a IS null AND b IS NOT null) THEN 0
WHEN (a IS null AND b IS null) THEN 1
WHEN (a=b) THEN 1
ELSE 0
END as result
from @combinations
order by result
Il retourne:
En d'autres termes, dans ce script, null
est traitée comme une valeur, par conséquent a='a'
et b=null
retours 0
, ce qui est ce que vous avez prévu. Seulement si les deux variables sont égales (ou les deux null
), elle renvoie 1
.