Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在SQL server中NULL=NULL的计算结果为false_Sql_Sql Server_Null - Fatal编程技术网

为什么在SQL server中NULL=NULL的计算结果为false

为什么在SQL server中NULL=NULL的计算结果为false,sql,sql-server,null,Sql,Sql Server,Null,在SQL server中,如果where子句中有nullParam=NULL,则它的计算结果始终为false。这是违反直觉的,给我造成了很多错误。我知道是空的和不是空的关键字是正确的方法。但是为什么SQL server会这样做呢?仅仅因为您不知道这两件事是什么,并不意味着它们是相等的。如果你想到NULL你想到的是“NULL”(字符串),那么你可能需要一个不同的平等测试,比如Postgresql的与不同,而与 从 表达式与表达式不同 表达式与表达式没有区别 对于非空输入,不同于与运算符相同。但是,

在SQL server中,如果where子句中有
nullParam=NULL
,则它的计算结果始终为false。这是违反直觉的,给我造成了很多错误。我知道
是空的
不是空的
关键字是正确的方法。但是为什么SQL server会这样做呢?

仅仅因为您不知道这两件事是什么,并不意味着它们是相等的。如果你想到
NULL
你想到的是“NULL”(字符串),那么你可能需要一个不同的平等测试,比如Postgresql的
不同,而

表达式
表达式不同

表达式
表达式没有区别

对于非空输入,
不同于
运算符相同。但是,如果两个输入都为null,则返回false;如果只有一个输入为null,则返回true。类似地,
与非空输入的
=
没有区别,但当两个输入都为空时,它返回true;当只有一个输入为空时,它返回false。因此,这些构造有效地起作用,就好像null是一个正常的数据值,而不是“未知的”

在这种情况下,可以将null视为“未知”(或“不存在”)。在这两种情况下,你都不能说它们相等,因为你不知道它们的价值。因此,null=null的计算结果为非true(false或null,取决于您的系统),因为您不知道表示它们相等的值。此行为在ANSI SQL-92标准中定义

编辑: 这取决于您的设置。如果禁用ANSI_null,则该值将计算为true。运行以下代码以获取示例

set ansi_nulls off

if null = null
    print 'true'
else
    print 'false'


set ansi_nulls ON

if null = null
    print 'true'
else
    print 'false'

也许这要看情况而定,但我认为
NULL=NULL
的计算结果是
NULL
,就像大多数以NULL作为操作数的操作一样。

NULL不等于任何东西,甚至不等于它本身。我个人理解NULL行为的方法是尽量避免使用它:)。

NULL在sql中是未知的,所以我们不能期望两个未知是相同的

但是,您可以通过将ANSI_NULLS设置为Off(默认情况下为On)来获得该行为 您将能够对空值使用=运算符

SET ANSI_NULLS off
if null=null
print 1
else 
print 2
set ansi_nulls on
if null=null
print 1
else 
print 2

MSDN对null和它们产生的三态逻辑有很好的描述

简而言之,SQL92规范将NULL定义为未知,并且以下运算符中使用的NULL会对未初始化的对象产生意外结果:

= operator NULL   true   false 
NULL       NULL   NULL   NULL
true       NULL   true   false
false      NULL   false  true

and op     NULL   true   false 
NULL       NULL   NULL   false
true       NULL   true   false
false      false  false  false

or op      NULL   true   false 
NULL       NULL   true   NULL
true       true   true   true
false      NULL   true   false
问题是:
一个未知等于另一个未知吗?
(空=空)
这个问题没有人能回答,所以它默认为true或false,具体取决于您的ansi_nulls设置

然而问题是:
这个未知变量未知吗?
这个问题完全不同,可以用正确的答案来回答

nullVariable=null正在比较值

nullVariable is null正在比较变量的状态

这里我希望澄清我的立场

NULL=NULL
计算为
FALSE
是错误的。黑客和先生正确回答了
NULL
。 这就是原因。Dewayne Christensen写信给我,在评论中:


既然现在是十二月,我们就用 季节性的例子。我有两件礼物 在树下。现在,你告诉我如果我 有没有两个相同的东西

它们可以是不同的,也可以是相等的,只有一个打开两个礼物,你才能知道。谁知道呢?你邀请了两个彼此不认识的人,他们都给了你同样的礼物——罕见但并非不可能§

所以问题是:这两个未知的礼物是相同的(相等的,=)?正确答案是:未知(即
NULL

此示例旨在证明“.(
false
null
,取决于您的系统)…”是正确答案-事实并非如此,只有
null
在3VL中是正确的(或者您可以接受给出错误答案的系统?)

这个问题的正确答案必须强调两点:

  • 三值逻辑(3VL)是违反直觉的(请参阅Stackoverflow和其他论坛上关于此主题的无数其他问题以确保)
  • 基于SQL的DBMS通常甚至不尊重3VL,它们有时给出错误的答案(正如原始海报断言的那样,在本例中SQL Server所做的那样)
因此,我重申:SQL不能强迫人们解释等式的自反属性,它指出:

对于任何x,x=x
§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§

。。在3VL中(
TRUE
FALSE
NULL
)。人们的期望值将符合2VL(
TRUE
FALSE
,即使在SQL中也对所有其他值有效),即
x=x
对于任何可能的x值,始终求值为
TRUE
,无例外

还要注意的是,空值是有效的“非值”(就像他们的辩护者假装的那样),可以将其作为属性值(?)指定为关系变量的一部分。因此,它们是每种类型(域)的可接受值,而不仅仅是逻辑表达式的类型

这就是我的观点:
NULL
,作为值,是一个“奇怪的野兽”。没有委婉的说法,我宁愿说:胡说八道

我认为这一表述更加清晰,争议更少——对不起,我的英语水平很差

这只是空值问题中的一个。如果可能,最好完全避免

§我们在这里关注的是价值观,因此这两个礼物始终是两个不同的物理对象这一事实不是有效的反对理由;如果你不是
CREATE TABLE MyTable
(
 key_col INTEGER NOT NULL UNIQUE, 
 data_col INTEGER
 CHECK (data_col = 55)
);

INSERT INTO MyTable (key_col, data_col)
   VALUES (1, NULL);
SELECT 1
WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)
where (value=@param Or @param is null) And id=@anotherParam
AND: The result of true and unknown is unknown, false and unknown is false,
while unknown and unknown is unknown.

OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.

NOT: The result of not unknown is unknown
SELECT 1 
WHERE EXISTS (
    SELECT NULL
    INTERSECT
    SELECT NULL
)
XYZ = NULL 
XYZ IS NULL
(NULLIF(ltrim( XYZ ),'') IS NULL)