混淆null比较与NOT结合

时间:2018-06-18 21:46:50

标签: sql-server tsql null

我意识到将NULL与任何其他值(包括NULL)进行比较将始终导致错误。

DECLARE @IsSet bit = NULL;

SELECT IIF(@IsSet = 1, 'true', 'false')
SELECT IIF(@IsSet != 1, 'true', 'false')

输出:

false
false

但这让我感到困惑:

SELECT IIF(NOT(@IsSet = 1), 'true', 'false')
SELECT IIF(NOT(@IsSet != 1), 'true', 'false')

这也输出:

false
false

我希望NOT将值翻转为TRUE。 (如果@IsSet对于第一个表达式设置为0,它会这样做)

似乎与null值的比较对括号外的布尔逻辑有一定的作用。

但是null比较并不比布尔逻辑强大:

SELECT IIF((@IsSet = 1) OR (1=1), 'true', 'false')
SELECT IIF((@IsSet != 1) OR (1=1), 'true', 'false')

返回:

true
true

我不明白这里发生了什么,但我认为这是故意的。但我不知道为什么。

有人可以解释为什么NOT(NULL!=1)不等于真。

2 个答案:

答案 0 :(得分:4)

NULL进行比较会产生UNKNOWN而不是TRUEFALSENOT UNKNOWN也会产生UNKNOWN,既不是TRUE也不是FALSE。一个人不能"翻转"使用UNKNOWNNOT设置为布尔值。

这种3向逻辑要求使用IS NULL or IS NOT NULL来测试NULL值而不是传统的布尔逻辑。

答案 1 :(得分:1)

您使用NOT的方式不正确。您将收到错误,如果您只执行NOT条件,如下所示:

SELECT NOT(@IsSet = 1)

当你在IIF条件中包含错误的NOT条件用法时,SQL服务器不会显示错误,但是语句将被评估为false输出。

如果要显式检查NULL值,可以采用以下练习。

SELECT IIF(@IsSet IS NULL, 'true', 'false')

最后,以下条件正在返回' true'在输出中,因为其中一个OR条件(1 == 1)总是评估为' true'因此IIF语句的总输出为真。

SELECT IIF((@IsSet = 1) OR (1=1), 'true', 'false')
SELECT IIF((@IsSet != 1) OR (1=1), 'true', 'false')