Sql中的空检查
请说明以下两者之间的区别: 1)Sql中的空检查,sql,sql-server,Sql,Sql Server,请说明以下两者之间的区别: 1) 其中student.name=ISNULL(@name,student.name) 及 2) 其中(student.name=@name或@name为空) 实际上,我有一个针对我名字的问题bug,当我使用第一个方法时,一些记录被跳过了。但是在我用eg 2替换它时得到了更正。如果系统设置为其他设置,null=anything为false 因此,第一个查询不会返回student.name为null的任何条目,即使@name为null,因为对于student.name
其中student.name=ISNULL(@name,student.name)
及
2) 其中(student.name=@name或@name为空)
实际上,我有一个针对我名字的问题bug,当我使用第一个方法时,一些记录被跳过了。但是在我用eg 2替换它时得到了更正。如果系统设置为其他设置,null=anything
为false
因此,第一个查询不会返回student.name
为null的任何条目,即使@name
为null,因为对于student.name为null的条目,比较结果为其中null=null
,而null=null
返回false第二条语句说,当学生名与@name匹配时选择记录,或者当没有指定姓名时,如果指定了@name,则为该姓名选择记录。如果@name为空,请选择所有记录。这与@name为NULL时表中的值无关
对于第一条语句,如果@name为NULL,它将使用与当前行的student.name相同的student.name
当@name和student.name都为空时
WHERE student.name = @name OR @name IS NULL -- the other part of the OR is true so records will be returned
及
由于NULL=NULL
返回false,因此不会返回该行的任何记录forISNULL()
是替换值,这意味着如果第一个参数为NULL,将替换该值。因此,如果@name
和student.name
都是null
,那么您基本上是在写:
student.name=NULL
它等于false(因为SQL中的null
被认为是未知的,并且永远不等于任何东西)
在第二个示例中,您使用IS
操作符测试空值,如果@name
为空,则返回true
WHERE student.name = ISNULL(@name, student.name)
及
除非student.name为null,否则为等效
WHERE (student.name = @name OR @name IS NULL)
可简化为:
WHERE COALESCE(student.name,'nul') = COALESCE(@name, student.name,'nul')
及
相当于
WHERE (student.name = @name OR @name IS NULL AND student.name IS NOT NULL)
这就是区别
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是否为null
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)
如果
@name
不为空,则第一个语句没有区别,如果两者都为空,则为NULL=NULL,这意味着当@name为空时,第一个查询将仅在student.name不为null时返回,第二个查询将返回所有行。正确,如果您传入的@name
为null,则第一个查询将返回任何非null student(例如'bob'='bob'
),其中与第二个查询一样,将返回所有内容,因为@name为null,所以所有行的都为true。是的,这是一个相当奇怪的问题。哇,太棒了……这真的消除了我的疑虑。这里主要强调的一点是Mike所说的“因为SQL中的null被认为是未知的,并且永远不等于任何东西”。就连我也觉得NULL==NULL返回True,但实际上它是FALSE。
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
select case when null = null then 1 else 0 end
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)