请建议有什么区别:
1)WHERE student.name = ISNULL(@name, student.name)
和
2)WHERE (student.name = @name OR @name IS NULL)
实际上,我有一个针对我的名字分配的问题错误,当我使用第一种方法时,其中一些记录被跳过。但是当我用例如 2 替换它时得到了纠正。
请建议有什么区别:
1)WHERE student.name = ISNULL(@name, student.name)
和
2)WHERE (student.name = @name OR @name IS NULL)
实际上,我有一个针对我的名字分配的问题错误,当我使用第一种方法时,其中一些记录被跳过。但是当我用例如 2 替换它时得到了纠正。
for的第二个参数ISNULL()
是替换值,表示如果第一个参数为 null 时将被替换的值。因此,如果两者都@name
和student.name
是null
,你基本上是在写:
student.name = NULL
这等于 false(因为null
在 SQL 中被认为是未知的,并且从不等于任何东西)。
在第二个中,您使用运算符来测试空值,如果为空IS
,它将返回。true
@name
这是区别
name |student.name |first_result |second_result |expected*
A |A |true |true |true
A |B |false |false |false
null |A |true |true |true
A |null |false |false |false
null |null |FALSE |TRUE |TRUE
*预期 - 一些人预期,但在我们的宇宙中不正确。
如您所见,两个值都为 NULL 时会出现差异,因为在这种情况下,您的第一个 WHERE 计算结果为:null = null(即 FALSE)。
您可以使用以下方法在 SQL Server 中进行检查:
select case when null = null then 1 else 0 end
这会给你0。
第二条语句说当学生姓名与@name 匹配或未指定姓名时选择记录如果指定了@name,则选择该姓名。如果@name 为空,则选择所有记录。这不关心@name 为 NULL 时表中的值是什么
对于第一条语句,如果@name 为NULL,它将使用student.name 与当前行的student.name 相同
当@name 和 student.name 都为 NULL 时
WHERE student.name = @name OR @name IS NULL -- the other part of the OR is true so records will be returned
和
WHERE student.name = ISNULL(@name, student.name) becomes WHERE NULL = NULL
因为NULL = NULL
返回 false,所以不会为该行返回任何记录
WHERE student.name = ISNULL(@name, student.name)
和
WHERE (student.name = @name OR @name IS NULL)
是等价的,除非 student.name 为空。
WHERE (student.name = @name OR @name IS NULL)
可以简化:
WHERE COALESCE(student.name,'nul') = COALESCE(@name, student.name,'nul')
和
WHERE student.name = ISNULL(@name, student.name)
相当于
WHERE (student.name = @name OR @name IS NULL AND student.name IS NOT NULL)
检查下面的示例,在第二个选项中,您可以在检查 name = @name 之前检查 @name 是否为空。
declare @name varchar(10) = null
declare @table table (name varchar(10))
insert into @table
select 'A'
UNION
SELECT null
---returns only A because null = column is always false
select * from @table where name = ISNULL(@name, name)
--returns all rows
select * from @table where (@name is null or name = @name)
set @name = 'A'
select * from @table where name = ISNULL(@name, name)
select * from @table where (@name is null or name = @name)
如果您设置了ANSI_NULLS系统设置,null = anything
则为 false。
所以第一个查询不会返回任何为 null 的条目student.name
,即使@name
是 null,因为比较计算结果where null=null
为 student.name 为 null 的条目,并null=null
返回 false