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 NULL
、IS NOT NULL
和 ISNULL()
进行比较。例如,您可以使用 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'
我在网上看到专门有这样一个 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 NULL
、IS NOT NULL
和 ISNULL()
进行比较。例如,您可以使用 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'