Sql server 针对一组其他变量(其中一个为NULL)测试一个变量,返回false
我有这个:Sql server 针对一组其他变量(其中一个为NULL)测试一个变量,返回false,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我有这个: DECLARE @First INT, @Second INT, @Third INT SET @First = 1 SET @Second = 2 SET @Third = NULL -- just for clarity IF(@First NOT IN (@Second, @Third)) BEGIN PRINT 'Here' -- expected this line to print... END ELSE BEGIN
DECLARE @First INT, @Second INT, @Third INT
SET @First = 1
SET @Second = 2
SET @Third = NULL -- just for clarity
IF(@First NOT IN (@Second, @Third))
BEGIN
PRINT 'Here' -- expected this line to print...
END
ELSE
BEGIN
PRINT 'There' -- but this line prints instead.
END
为什么它会进入“else”块?如果我这样尝试,我会得到预期的结果:
IF(@First IN (@First, @Second, @Third))
BEGIN
PRINT 'Here' -- this line prints, as expected.
END
ELSE
BEGIN
PRINT 'There'
END
为什么使用中的(其中一个值为NULL
)检查一组其他值中是否不存在一个值时返回false
我肯定有人会告诉我,出于某种深奥的SQL-y原因,这是预期的行为,但我想我们都可以同意,这是一种危险的“默认”,可能会让粗心的人绊倒。相反,阅读NULL
表示“没有值”,在这种情况下,最好将NULL
视为含义,“不清楚其价值是什么。”
根据对NULL
的理解,现在当这个表达式将@First
与序列中的每个值进行比较时,我们不能肯定地说@First
的值不在序列中,因为不清楚@Third
的值是什么
第二个代码示例之所以有效,是因为您可以明确地说序列中确实存在@First
。而不是将NULL
理解为“没有值”,在这种情况下,最好将NULL
理解为“不清楚值是什么”
根据对NULL
的理解,现在当这个表达式将@First
与序列中的每个值进行比较时,我们不能肯定地说@First
的值不在序列中,因为不清楚@Third
的值是什么
第二个代码示例之所以有效,是因为您可以明确地说,@First
确实存在于序列中。经典的示例不在带有NULL
值的陷阱中。这不是深奥的,只是简单如下:
@First IN (@Second, @Third)
<=>
@First = @Second OR @First = @Third
@First IN(@Second,@Third)
@第一个=@第二个或@First=@第三个
现在基于:
“not(A或B)”与“(not A)and(not B)”相同
@第一个不在(@第二个,@第三个)
@第一个@第二个和第一个@第三个
1 2和1 NULL=>NULL
true和NULL=>NULL——转到else分支
谜团已经解开。经典的不在陷阱中且值为空的例子。这不是深奥的,只是简单的如下:
@First IN (@Second, @Third)
<=>
@First = @Second OR @First = @Third
@First IN(@Second,@Third)
@第一个=@第二个或@First=@第三个
现在基于:
“not(A或B)”与“(not A)and(not B)”相同
@第一个不在(@第二个,@第三个)
@第一个@第二个和第一个@第三个
1 2和1 NULL=>NULL
true和NULL=>NULL——转到else分支
谜团已解。和null始终无法用于“if”块中的“else”分支。@roryap Yes,只有true才能用于if分支,其他任何内容都可以转到else
NOT in
中,这很棘手,应始终与NOT null
值一起使用。null始终无法用于“if”块中的“else”分支block.@roryap是的,只有true才能进入IF分支,其他任何内容都可以进入else
<代码>不在
中很棘手,应始终与不可为空
值一起使用,该值根据标题返回未知
不假
。SQL使用三值逻辑。是的,根据答案我现在知道了。不过,很难确定这一点。我试图找出如何观察@First NOT IN(@Second,@Third)
的值。SQL server没有布尔数据类型。如果您是这样要求的,则不能将谓词的结果直接赋给变量或列。您也不能执行if(将1转换为位)
,也不能在该方向将位视为布尔值。有一个SQL标准布尔数据类型,但当前未在SQL server中实现。该数据类型的文档中包含以下警告:“与其他SQL server数据类型不同,布尔数据类型不能指定为表列或变量的数据类型,也不能在结果集中返回。”它返回每个标题的unknown
notfalse
。SQL使用三值逻辑。是的,根据答案我现在知道了。不过,很难确定这一点。我试图找出如何观察@First NOT IN(@Second,@Third)
的值。SQL server没有布尔数据类型。如果您是这样要求的,则不能将谓词的结果直接赋给变量或列。您也不能执行if(将1转换为位)
,也不能在该方向将位视为布尔值。有一个SQL标准布尔数据类型,但当前未在SQL server中实现。该数据类型的文档中包含以下警告:“与其他SQL server数据类型不同,布尔数据类型不能指定为表列或变量的数据类型,也不能在结果集中返回。”