SQL Server 2014 Where 子句中的错误结果,帮助我理解原因

SQL Server 2014 Wrong result in Where clause, help me to understand why

我在网上看到专门有这样一个 where 子句:

where Location2 <> ''

列值 Null 的计算结果应为真。

此行为在 SQL Server 2014 中对我一直不起作用。该 where 子句将排除我的 Null 列。我们可以编写一个查询来解决这个问题,但我需要知道会发生什么以及这是否是新行为。

谢谢。

null与任何东西相比,反正不是真的,总是失败,检查这个:

NULL = NULL -- fails
NULL <> '' -- fails: can be translated as "it's not different to '' "
NULL = '' -- fails: can be translated as "it's not equal to '' ", surprised?

你应该使用

where Location2 <> '' or Location2 is null

已添加:(呃...从下面的@Bacon Bits 评论中复制并粘贴,谢谢)

实际上,所有这些表达式的真值都是未知的。当将 UNKNOWN 与 AND 和 OR 结合使用时,复杂性就来了。 UNKNOWN 有点像 FALSE,但有点古怪。底线:始终处理您的 NULLS。

答案取决于 ANSI_NULLS 的值。

When SET ANSI_NULLS is ON, a SELECT statement that uses WHERE column_name = NULL returns zero rows even if there are null values in column_name. A SELECT statement that uses WHERE column_name <> NULL returns zero rows even if there are nonnull values in column_name.

When SET ANSI_NULLS is OFF, the Equals (=) and Not Equal To (<>) comparison operators do not follow the ISO standard. A SELECT statement that uses WHERE column_name = NULL returns the rows that have null values in column_name. A SELECT statement that uses WHERE column_name <> NULL returns the rows that have nonnull values in the column. Also, a SELECT statement that uses WHERE column_name <> XYZ_value returns all rows that are not XYZ_value and that are not NULL.

推测您正在使用SET ANSI_NULLS ON进行操作。正如文档所说,NULL 表示“未知”,任何处理未知值的操作也是未知的。

如果您想直接与 NULL 进行比较,可以在查询之前立即设置 SET ANSI_NULLS OFF,然后再将其重新打开。例如:

declare @x varchar(10)

set ansi_nulls on
if @x <> '' select 'yes' else select 'no' -- returns "no"

set ansi_nulls off
if @x <> '' select 'yes' else select 'no' -- returns "yes"

更好的选择是明确地与 IS NULLIS NOT NULLISNULL() 进行比较。例如,您可以使用 ISNULL 来简化这样的比较:

declare @x varchar(10)

set ansi_nulls on
if isnull(@x, '') <> '' select 'yes' else select 'no' -- returns "no"

set ansi_nulls off
if isnull(@x, '') <> '' select 'yes' else select 'no' -- returns "no"

如果你好奇ANSI_NULLS是否在执行过程中启用,你可以检查@@OPTIONS位32:

if @@OPTIONS & 32 = 32
    select 'ANSI_NULLS is ON'
else
    select 'ANSI_NULLS is OFF'