而后当你用 SET 关键字给变量赋值的话,sql server 将为这个值分配内存空间并将地址存放在变量列表(variable table)中。若是你再次为这个变量赋值的话新的内存地址将替换旧的地址。 sql
下面咱们就来讨论一下 “= NULL”和“IS NULL”的区别。 数据库
“= NULL” post
“= NULL”是值表达式。意味着,这个表达式会判断是否已经为变量正确设置了值。事实上咱们是能够设置一个变量的值为 NULL 的(若是设置变量 = NULL,这就说明变量的值是未知的 unknown)。参考下面的代码。 .net
DECLARE @val CHAR(4) 3d
SET @val = NULL server
咱们显式给变量赋值 NULL,sql server会为变量分配内存空间并指出变量值是未知的 unknown,所以下面的表达式将返回 true(由于咱们已经经过 SET @val = NULL 为变量分配了内存空间): 内存
If @val = NULL get
但若是咱们像下面的代码段同样在申明变量的时候不给变量赋值: table
DECLARE @val CHAR(4) class
If @val = NULL
表达式将返回 false。
致使这种状况的缘由是,在没有给变量赋值的状况下,sql server 是不会为变量分配内存空间,所以地址是未知的就没法进行值的比较了。
Note: 上面的示例结果与 ANSI_NULLS (ON|OFF) 的设置有关。
“IS NULL”
“IS NULL”的状况就有点微妙,在须要比较变量值是否是为 NULL 的时候它应该是首选的用法。IS NULL 会同时检查变量地址和变量的地址所指向的值是否是未知的(unknown)。研究一下下面的代码:
上面两个表达式都会返回 TRUE, 缘由是 IS NULL 同时比较地址和值是否是未知的。
环境变量 SET ANSI_NULLS (ON|OFF) 的设置对 “= NULL”的表达式会有很大的影响,下面的段落摘录自sql server 的帮助,它很好的解释了这一因素。(SET ANSI_NULLS 详细的说明参考sql server 帮助)
SQL-92 标准要求对空值的等于 (=) 或不等于 (<>) 比较取值为 FALSE。当 SET ANSI_NULLS 为 ON 时,即便 column_name 中存在空值,使用 WHERE column_name = NULL 的 SELECT 语句仍返回零行。即便 column_name 中存在非空值,使用 WHERE column_name <> NULL 的 SELECT 语句仍返回零行。
当 SET ANSI_NULLS 为 OFF 时,等于 (=) 和不等于 (<>) 比较运算符不听从 SQL-92 标准。使用 WHERE column_name = NULL 的 SELECT 语句返回 column_name 中含有空值的行。使用 WHERE column_name <> NULL 的 SELECT 语句返回列中含有非空值的行。此外,使用 WHERE column_name <> XYZ_value 的 SELECT 语句返回全部非 XYZ 值和非 NULL的行。
当 SET ANSI_NULLS 为 ON 时,全部对空值的比较均取值为 UNKNOWN。当 SET ANSI_NULLS 为 OFF 时,若是数据值是 NULL,则全部数据对空值的比较将取值为 TRUE。若是未指定,则应用当前数据库的 ANSI nulls 选项的设置。
为使脚本按预期运行,无论 ANSI nulls 数据库选项或 SET ANSI_NULLS 的设置是什么,在可能包含空值的比较中使用 IS NULL 和 IS NOT NULL。
因此咱们在须要判断NULL的时候最好使用 IS NULL 和 IS NOT NULL。尽可能避免使用 = NULL 和 <> NULL, 由于后者会产生非预期的效果。
在 SET ANSI_NULLS 设置不一样时下面的 sql 语句会产生不一样结果:
SELECT * FROM t1 WHERE a = NULL
SELECT * FROM t1 WHERE a <> NULL
SELECT * FROM t1 WHERE a IS NULL
原文地址 http://baodr.com/post/2008/04/IS-NULL-and-3d-NULL-e59ca8-sql-server-e4b8ade79a84e58cbae588ab.aspx