所以我有一个简单的查询返回产品列表
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
返回
010-00749-01 00000000-0000-0000-0000-000000000000
010-00749-01 NULL
哪个是正确的,所以我只想要CategoryID不是'00000000-0000-0000-0000-000000000000'的产品,所以我有
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
AND (CategoryID <> '00000000-0000-0000-0000-000000000000')
但是这没有结果。所以我将查询更改为
SELECT Model, CategoryID
FROM Products
WHERE (Model = '010-00749-01')
AND ((CategoryID <> '00000000-0000-0000-0000-000000000000') OR (CategoryID IS NULL))
返回预期结果
010-00749-01 NULL
有人可以向我解释这种行为吗? MS SQL Server 2008
答案 0 :(得分:9)
查看Books Online的完整参考资料 - 默认情况下,ANSI_NULLS表示您需要使用已完成的方法。否则,您可以在查询开始时将该设置关闭以切换行为。
当SET ANSI_NULLS为ON时,为SELECT 使用WHERE column_name的语句 = NULL返回零行,即使column_name中有空值也是如此。一个 使用WHERE的SELECT语句 column_name&lt;&gt; NULL返回零行 即使有非空值 列名。
...
当SET ANSI_NULLS时 是ON,所有与null的比较 值评估为UNKNOWN。当SET ANSI_NULLS为OFF,比较所有 针对空值的数据评估为 如果数据值为NULL,则为TRUE。
这是一个简单的例子,用于演示与NULL比较的行为:
-- This will print TRUE
SET ANSI_NULLS OFF;
IF NULL <> 'A'
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
-- This will print FALSE
SET ANSI_NULLS ON;
IF NULL <> 'A'
PRINT 'TRUE'
ELSE
PRINT 'FALSE'
答案 1 :(得分:2)
通常,您必须记住NULL通常表示UNKNOWN。这意味着如果你说CategoryID <> '00000000-0000-0000-0000-000000000000'
,你必须假设查询只会返回它知道符合你标准的值。由于存在NULL(UNKNOWN)结果,因此实际上并不知道该记录是否符合您的条件,因此不会在数据集中返回。
答案 2 :(得分:1)
看看这个:
1=1 --true
1=0 --false
null=null --false
null=1 --false
1<>1 --false
1<>0 --true
null<>null --false
null<>1 --false <<<--why you don't get the row with: AND (CategoryID <> '00000000-0000-0000-0000-000000000000')
答案 3 :(得分:1)
基本上,NULL是缺少任何值。因此,尝试将CategoryId中的NULL与查询中的varchar值进行比较将始终导致错误评估。
您可能想尝试使用COALESCE功能,例如:
SELECT ModelId, CategoryID
FROM Products
WHERE (ModelId = '010-00749-01')
AND ( COALESCE( CategoryID, '' ) <> '00000000-0000-0000-0000-000000000000' )
修改强>
如AdaTheDev
所述,COALESCE函数将否定CategoryID列上可能存在的任何索引,这可能会影响查询计划和性能。
答案 4 :(得分:0)
Null得到特殊待遇。您需要显式测试null。见http://msdn.microsoft.com/en-us/library/ms188795.aspx
答案 5 :(得分:0)
您可以尝试使用Coalesce
功能为null
字段设置默认值:
SELECT Model , CategoryID
FROM Products
WHERE Model = '010-00749-01'
AND Coalesce(CategoryID,'') <> '00000000-0000-0000-0000-000000000000'
我认为问题在于你对NULL
的理解,这基本上意味着什么都没有。你无法将任何东西与任何东西进行比较,就像你不能将数字除以0.它只是数学/科学的规则。
修改强> 正如Ada所指出的,这可能导致索引字段不再使用索引。
解决方案:
create index ... coalesce(field)
not null
约束以防止NULL出现