where子句中的SQL和NULL值

Gre*_*reg 9 sql sql-server null sql-server-2008

所以我有一个简单的查询返回产品列表

SELECT     Model, CategoryID
FROM         Products
WHERE     (Model = '010-00749-01') 
Run Code Online (Sandbox Code Playgroud)

这回来了

010-00749-01    00000000-0000-0000-0000-000000000000
010-00749-01    NULL
Run Code Online (Sandbox Code Playgroud)

这是正确的,所以我只想要那些CategoryID不是'00000000-0000-0000-0000-000000000000'的产品,所以我有

SELECT     Model, CategoryID
FROM         Products
WHERE     (Model = '010-00749-01') 
AND (CategoryID <> '00000000-0000-0000-0000-000000000000') 
Run Code Online (Sandbox Code Playgroud)

但这没有结果.所以我将查询更改为

SELECT     Model, CategoryID
FROM         Products
WHERE     (Model = '010-00749-01') 
AND ((CategoryID <> '00000000-0000-0000-0000-000000000000') OR  (CategoryID  IS NULL))
Run Code Online (Sandbox Code Playgroud)

哪个返回预期结果

010-00749-01    NULL
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释这种行为吗?MS SQL Server 2008

Ada*_*Dev 9

查看联机丛书的完整参考- 默认情况下,ANSI_NULLS表示您需要使用您已完成的方法.否则,您可以在查询开始时将该设置关闭以切换行为.

当SET ANSI_NULLS为ON时,即使column_name中存在空值,使用WHERE column_name = NULL的SELECT语句也会返回零行.使用WHERE column_name <> NULL的SELECT语句返回零行,即使column_name中存在非空值也是如此.
...
当SET ANSI_NULLS为ON时,对空值的所有比较都计算为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'
Run Code Online (Sandbox Code Playgroud)