黑马程序员技术交流社区

标题: 数据库操作语句"is"和"=" [打印本页]

作者: 杨曾荣    时间: 2012-3-16 20:48
标题: 数据库操作语句"is"和"="
"="含有判断的意思,而"="与"is"的区别
作者: 方杰    时间: 2012-3-16 22:35
2者在特定的地方有去别。如 NULL 值,
在SQL 中你要判断一个值是否为 NULL 用 : select * from table where  name is NULL
不能用name=NULL。
作者: 王长森    时间: 2012-3-16 23:16
is 是判断,=两边的值相等
作者: 徐振升    时间: 2012-3-17 09:35
当我们在 sql server 中用 DECLARE 申明一个变量时, sql server 将会把变量存储在SQLs 内存空间的变量列表区域(variable table),变量列表中包含了变量的名称和存储地址。然而如果我们在创建变量的时候并没有给变量赋值的话,sql server是没有为变量分配内存的,因此变量并没有在内存中被定义。
然后当你用 SET 关键字给变量赋值的话,sql server 将为这个值分配内存空间并将地址存放在变量列表(variable table)中。如果你再次为这个变量赋值的话新的内存地址将替换旧的地址。

“= NULL”

    “= NULL”是值表达式。意味着,这个表达式会判断是否已经为变量正确设置了值。事实上我们是可以设置一个变量的值为 NULL 的(如果设置变量 = NULL,这就说明变量的值是未知的 unknown)。参考下面的代码。

DECLARE @val CHAR(4)

SET @val = NULL


    我们显式给变量赋值 NULL,sql server会为变量分配内存空间并指出变量值是未知的 unknown,因此下面的表达式将返回true(因为我们已经通过 SET @val = NULL 为变量分配了内存空间):

If @val = NULL

    但如果我们像下面的代码段一样在申明变量的时候不给变量赋值:

DECLARE @val CHAR(4)

If @val = NULL


   表达式将返回 false。  

    导致这种情况的原因是,在没有给变量赋值的情况下,sql server 是不会为变量分配内存空间,因此地址是未知的就无法进行值的比较了。

Note: 上面的示例结果与 ANSI_NULLS (ON|OFF) 的设置有关。

“IS NULL”

    “IS NULL”的情况就有点微妙,在需要比较变量值是不是为 NULL 的时候它应该是首选的用法。IS NULL 会同时检查变量地址和变量的地址所指向的值是不是未知的(unknown)。
研究一下下面的代码:

DECLARE @val CHAR(4)
If @val IS NULL
            PRINT 'TRUE'
ELSE
            PRINT 'FALSE'

SET @val = NULL
If @val IS NULL
            PRINT 'TRUE'
ELSE
            PRINT 'FALSE'

上面两个表达式都会返回 TRUE, 原因是 IS NULL 同时比较地址和值是不是未知的。



ANSI_NULLS
SET ANSI_NULLS (ON|OFF)
     环境变量 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


作者: 杨曾荣    时间: 2012-3-18 14:05
徐振升 发表于 2012-3-17 09:35
当我们在 sql server 中用 DECLARE 申明一个变量时, sql server 将会把变量存储在SQLs 内存空间的变量列表 ...

太专业了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2