NOT
总是表示否定。T-SQL行为的原因在于,null
值根据数据库配置设置(称为ansi_nulls
)以特殊方式处理。根据此设置,null
被视为与任何其他值相同,或者被视为“未设置值”。在这种情况下,包含null值的所有表达式都被视为无效。
此外,表达式
(@a IS NULL AND @b IS NULL)
OR
@a = @b
仅涵盖了两个变量都为NULL
的情况,不处理@a
或@b
其中一个为NULL
的情况。如果发生这种情况,则结果取决于ansi_nulls
的设置:如果它是on
,那么@a = @b
的结果始终为false
,如果其中一个变量为NULL
。
如果ansi_nulls
为off
,则将NULL
视为一个值,并按预期行为进行处理。
为避免此类意外行为,您应该按以下方式涵盖所有情况:
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
请注意,在此示例中,所有空值情况都在检查
@a=@b
之前处理(在
CASE
语句中,
WHEN
按照它们出现的顺序进行处理,如果条件匹配,则处理完成并返回指定的值)。
为了测试所有可能的(相关)组合,您可以使用此脚本:
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
它返回:
![result of query](https://istack.dev59.com/Gdolm.webp)
换句话说,在这个脚本中,
null
被视为一个值,因此
a='a'
和
b=null
返回
0
,这是您所期望的。只有当两个变量都相等(或都为
null
)时,它才返回
1
。
set ansi_nulls off;
,你就会看到不同之处。这样,在至少有一个操作数为NULL
的比较中,你就不会得到NULL
,而是得到一个false
。 - Tim SchmelterIS DISTINCT FROM
操作符(在MySQL中为<=>
)。 - Owen