为什么NULL = NULL在SQL Server中评估为false

Byr*_*ock 137 sql sql-server null

在SQL Server中,如果 nullParam=NULL在where子句中,它总是计算为false.这是违反直觉的,并且给我带来了许多错误.我确实理解IS NULLIS NOT NULL关键字是正确的方法.但是为什么SQL服务器会以这种方式运行?

Sco*_*vey 198

在这种情况下,将null视为"未知"(或"不存在").在任何一种情况下,你都不能说它们是平等的,因为你不知道它们中的任何一个的价值.因此,null = null的计算结果为true(false或null,具体取决于您的系统),因为您不知道值是否相等.此行为在ANSI SQL-92标准中定义.

编辑:这取决于你的ansi_nulls设置.如果你关闭ANSI_NULLS,这将评估为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'
Run Code Online (Sandbox Code Playgroud)

  • +1.这是问题中"为什么"的正确答案.令人惊讶的是,我现在看到的有多少答案在描述某些东西的工作方面技术上是正确的,但未能涵盖有趣的事情__why__事情是如此. (30认同)
  • @ MaD70 - 所以你不同意标准,并为此投票?很好,谢谢. (12认同)
  • x = x仅在x为_known_值时才成立.NULL是_unknown_值的文本表示.如果您有两个未知值,则无法最终说明其平等性.我相信这几个世纪也是如此. (11认同)
  • 换句话说,SQL表达式中的每个"NULL"都可以被视为_distinct_数学变量.所以表达式`NULL = NULL`应该被视为`x = y`,其中`x`和`y`是未绑定的变量.现在如果有人问你,`x = y`的价值是多少?唯一合理的答案是"有些`z`".所以我们有`(x = y)= z` - 或者,将它转录回SQL,`(NULL = NULL)= NULL`. (9认同)
  • 这里没有违反反身性,因为NULL不是值集的成员(域,关系术语).NULL _不是value_.它是未知值的占位符. (8认同)
  • SQL NULL与IEEE浮点NaN没有任何不同,你也有`(NaN == NaN)== false &&(NaN!= Nan)== false &&(NaN <NaN)== false && ...` - 因为,如果它不是一个数字,你就不能说太多了; 这是未知的事情.即使对以前从未见过它的人不直观,这个概念也是合理的. (5认同)
  • 从12月开始,让我们使用一个季节性的例子.我在树下有两件礼物.现在,你告诉我是否有两个相同的东西. (3认同)
  • 它更像是"依赖于一个系统的配置".ANSI SQL标准在这方面是明确的(它是3VL),但由于传统原因,实现通常不能只坚持它并且在模式上没有选择.因此`ANSI_NULLS`和其他这样的琐事.在任何情况下,您_can_配置MSSQL以正确处理NULL. (2认同)
  • 不,我不在乎你说了多少次,NULL = NULL是假的.就像1 - 0是假的,除了你比较两个不同和未知的对象.如果他们不能被认为是平等的,那么平等是错误的."如果A与B完全相同,则返回TRUE,ELSE返回FALSE".那个逻辑对你来说有点清楚吗?如果它们不是等于,那么相等比较必须返回false.我不知道为什么你很难抓住这个概念,我很害怕. (2认同)
  • @Pavel Minaev:我知道这是一个古老的讨论,但MaD70提出了一些被忽略的有效点.如果我给你两个盒子,其中的内容是你不知道的,并问:"方框A中的东西是否与方框B中的东西相同?" 你说,"不",这是一个问题.事实是,你不知道它们是否相同,所以你不能有效地说"是"**或**"否".它类似于除零:我问一个无法回答的问题.默认答案是"假",是纯粹的愚蠢(或迟钝,无论你喜欢哪个).MaD70是对的. (2认同)
  • 上面的争论很愚蠢。从逻辑和常识来看,“未知 1 = 未知 2”的正确答案既不是真也不是假。这是“我不知道”。这里的缺陷是试图将“我不知道”塞进“是真是假?”。SQL 实现者大概认为说“False”比说“True”更安全。也许吧,但正如 MaD70 在他的回答中指出的那样,这仍然是一个逻辑缺陷。结果应该是“NULL”(代表“我不知道”)。也就是说,应该将“缺乏知识”传播到封闭查询。 (2认同)

Nei*_*gan 124

弗兰克多大了?我不知道(null).

雪莉多大了?我不知道(null).

弗兰克和雪莉的年龄相同吗?

正确答案应该是"我不知道"(null),而不是"不",因为Frank和Shirley 可能是同一年龄,我们根本就不知道.

  • 喜欢你解释的方式 (20认同)
  • @harshitgupta没有比这更好的方法了.不幸的是,这不是公认的答案:) (3认同)
  • 我不同意null表示"未知".它实际意味着什么是"没有数据".这可能用于表示信息未知的情况,但实际上更可能用于表示某些信息不存在.继续你的例子:弗兰克的中间名是什么?他没有(null).雪莉的中间名是什么?她没有(null).弗兰克和雪莉有同样的中间名吗?是?没有?不知道?我可以看到一个"不"的论证,我可以看到"不知道"的论证,但除非你过于文字,否则没有真正的"是"论证. (3认同)
  • @Richiban你的问题显然是肯定的。弗兰克没有中间名。雪莉没有中间名。因此他们确实有相同的中间名。 (3认同)
  • @richiban 我不同意。不存在一行意味着“没有数据” (2认同)
  • @NeilMcGuigan 如果对于具有自己的表的数据来说确实如此,但是对于列中表示的数据呢?难道你不会用“null”来表示数据不存在吗?“未知”是数据缺失的一个非常具体的原因。 (2认同)
  • 但是`null = null`会产生`FALSE`,而不是`NULL`。 (2认同)

MaD*_*D70 26

在这里,我希望澄清我的立场.

NULL = NULL评估为FALSE是错误的.黑客和先生正确回答NULL.这就是原因.Dewayne Christensen在给Scott Ivey的评论中写信给我:

从12月开始,让我们使用一个季节性的例子.我在树下有两件礼物.现在,你告诉我是否有两个相同的东西.

它们可以是不同的,也可以是平等的,直到一个打开两个礼物,你才知道.谁知道?你邀请了两个彼此不认识的人,两人都给了你同样的礼物 - 很少见,但并非不可能§.

所以问题是:这两个UNKNOWN呈现相同(等于,=)?正确答案是:UNKNOWN(即NULL).

这个例子的目的是为了证明 "..(false或者null,取决于你的系统).."是一个正确的答案 - 它不是,只有 NULL在3VL中是正确的(或者你可以接受一个给出错误答案的系统吗? )

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

  • 三值逻辑(3VL)是违反直觉的(在Stackoverflow和其他论坛上看到关于这个主题的无数其他问题以确保);
  • 基于SQL的DBMS通常甚至不尊重3VL,它们有时会给出错误的答案(正如原始海报断言,SQL Server在这种情况下做的那样).

所以我重申:SQL没有任何好处强迫一个人解释相等的反身属性,这表明:

for any x, x = x §§(用简单的英语:无论话语的世界如何,"事物"总是等于它自己).

..在3VL( ,TRUE,).FALSE NULL人们的期望将符合2VL(TRUE,FALSE即使在SQL中对所有其他值也有效),即x = x 总是评估为 TRUE x的任何可能值 - 没有例外.

另请注意,NULL是有效的" 非值 "(因为他们的辩护者假装它们),哪个可以作为关系变量的一部分指定为属性值(??).因此,它们是每种类型(域)的可接受值,而不仅仅是逻辑表达式的类型.

这是我的观点:NULL作为价值,是一个"奇怪的野兽".没有委婉语,我更愿意说:胡说八道.

我认为这个表述更清晰,更少争议 - 对不起我的英语水平很差.

这仅仅是一个的空值的问题.如果可能的话,最好完全避免它们.

§我们关注这里的价值观,所以这两个礼物总是两个不同的物体,这不是一个有效的反对意见; 如果你不相信我很抱歉,这不是解释价值和"对象"语义之间差异的地方(关系代数从一开始就有价值语义 - 参见Codd的信息原理;我认为一些SQL DBMS实现者不要甚至不关心常见的语义.

§§据我所知,这是一个被接受的公理(以某种形式或另一种形式,但总是以2VL的形式解释)因为古代而且正是因为如此直观.3VL(实际上是一个逻辑家族)是一个更近期的发展(但我不确定什么时候开始发展).

旁注:如果有人将底部,单元选项类型作为尝试来证明SQL NULL的合理性,那么只有经过一次非常详细的检查才能说明我将如何使用NULL实现具有声音类型系统的SQL实现并最终澄清,什么是NULL(这些"值 - 不是很多值")确实是.


以下我将引用一些作者的话.任何错误或遗漏都可能是我的,而不是原作者.

Joe Celko关于SQL NULLs

我在这个论坛上经常引用Joe Celko.显然他在这里是一位备受尊敬的作家.所以,我对自己说:"他写的关于SQL NULL的内容是什么?他如何解释NULL很多问题?".我的一个朋友有一个电子书版本的Joe Celko的智能手机SQL:高级SQL编程,第3版.让我们来看看.

一,目录.最让我印象深刻的是提到NULL的次数以及最多变的背景:

3.4算术和NULL 109
3.5将值转换为NULL 110
3.5.1 NULLIF()函数110
6 NULL:SQL中缺少数据185
6.4比较NULL 190
6.5 NULL和逻辑190
6.5.1子查询中的NULLS谓词191
6.5.2标准SQL解决方案193
6.6数学和NULL 193
6.7函数和NULL 193
6.8 NULL和主机语言194
6.9 NULL的设计建议195
6.9.1避免来自主机程序的NULL 197
6.10关于多个NULL值的说明198
10.1 IS NULL谓词241
10.1. 1个NULL源242
...

等等.它给我带来了"令人讨厌的特殊情况".

我将通过本书的摘录进入其中一些案例,并出于版权原因试图将自己限制在必要的范围内.我认为这些引用属于"合理使用"原则,他们甚至可以刺激购买这本书 - 所以我希望没有人会抱怨(否则我将需要删除大部分内容,如果不是全部的话).此外,出于同样的原因,我将不再报告代码片段.对于那个很抱歉.购买这本书,阅读有关数据推理的内容.

以下是括号内的页码.

NOT NULL约束(11)

最重要的列约束是NOT NULL,它禁止在列中使用NULL.经常使用此约束,并仅在您有充分理由时将其删除.当您对数据进行查询时,它将帮助您避免NULL值的复杂化.

这不是一个价值 ; 它是一个标记,用于存放值可能存在的位置.

再次这个"价值但不是很有价值"的废话.其余对我来说似乎很明智.

(12)

简而言之,NULL会导致SQL中出现大量不规则的特性,我们将在后面讨论.最好的办法就是在无法避免的情况下记住NULL的情况和规则.

适用于SQL,NULL和无限:

(104)第3章:SQL中的数字数据

由于几个原因,SQL还没有接受IEEE的数学模型.

...

如果在SQL中允许使用IEEE数学规则,那么我们需要无限的类型转换规则以及在转换后表示无限精确数值的方法.人们对NULL有足够的麻烦,所以我们不要去那里.

SQL实现未定义NULL在特定上下文中的实际含义:

3.6.2指数函数(116)

问题是当(x <= 0)时对数是未定义的.一些SQL实现返回错误消息,一些返回NULL和DB2/400; 版本3发行版1返回*NEGINF("负无穷大"的缩写)作为结果.

Joe Celko引用David McGoveran和CJ Date:

6 NULL:SQL中缺少数据(185)

在他们的书"Sybase和SQL Server指南"中,David McGoveran和CJ Date说:"这是作者的观点,而不是NULL,至少目前在SQL中定义和实现,比它们的价值要大得多,应该避免; 它们表现出非常奇怪和不一致的行为,可能是错误和混乱的丰富来源.(请注意,这些注释和批评适用于任何支持SQL样式NULL的系统,而不仅仅适用于SQL Server.)"

NULLs作为吸毒成瘾:

(187分之186)

在本书的其余部分,我将敦促你不要使用它们,这看似矛盾,但事实并非如此.将NULL视为药物; 正确使用它,它适用于你,但滥用它,它可以毁了一切.您最好的策略是尽可能避免使用NULL,并在必要时正确使用它们.

我在这里的唯一反对意见是"正确使用它们",它与特定的实现行为非常相互作用.

6.5.1子查询谓词中的NULLS(191/192)

人们忘记了子查询经常隐藏与NULL的比较.考虑这两个表:

...

结果将为空.这是违反直觉的,但是正确的.

(分隔器)

6.5.2标准SQL解决方案(193)

SQL-92通过添加表单的新谓词解决了一些3VL(三值逻辑)问题:

<搜索条件> IS [NOT] TRUE | FALSE | 未知

但是UNKNOWN本身就是问题的根源,所以CJ Date在下面引用的书中推荐给第4.5.在SQL中避免空值:

  • 不要在任何上下文中使用关键字UNKNOWN.

在UNKNOWN上阅读"ASIDE",也在下面链接.

6.8 NULL和主机语言(194)

但是,您应该知道在必须将NULL传递给宿主程序时如何处理NULL.没有为其定义嵌入的标准宿主语言支持NULL,这是避免在数据库模式中使用它们的另一个好理由.

(分隔器)

6.9 NULL的设计建议(195)

尽可能在所有列上声明所有基表的NOT NULL约束是个好主意.NULL会使不熟悉SQL的人感到困惑,而NULL则很昂贵.

异议:NULL甚至会让那些熟悉SQL的人感到困惑,见下文.

(195)

在FOREIGN KEY中应该避免使用NULL.SQL允许这种"怀疑的好处"关系,但它可能导致涉及连接的查询中的信息丢失.例如,给定Inventory中由Orders表引用为FOREIGN KEY的部件号代码,您将无法获得具有NULL的部件的列表.这是一种强制性关系; 你不能订购一个不存在的零件.

(分隔器)

6.9.1避免主机程序出现NULL(197)

您可以避免使用某些编程规则将NULL添加到主机程序的数据库中.

...

  1. 确定缺失数据对编程和报告的影响: 带有NULL的数字列是一个问题,因为使用聚合函数的查询可能会产生误导性结果.

(分隔器)

(227)

空集的SUM()始终为NULL.使用此技巧时最常见的编程错误之一是编写一个可以返回多行的查询.如果你没有想到它,你可能已经写了最后一个例子:...

(分隔器)

10.1.1 NULL的来源(242)

记住NULL可能发生的位置很重要.它们不仅仅是列中的可能值.空集,OUTER JOIN,带NULL的算术表达式和OLAP运算符的聚合函数都返回NULL.这些结构通常在VIEW中显示为列.

(分隔器)

(301)

当您尝试将IN谓词转换为EXISTS谓词时,会发现NULL的另一个问题.

(分隔器)

16.3 ALL谓词和极值函数(313)

起初这是违反直觉的,这两个谓词在SQL中是不一样的:

...

但是你必须记住极值函数的规则 - 它们在返回更大或更小的值之前删除所有的NULL.ALL谓词不会丢弃NULL,因此您可以在结果中获取它们.

(分隔器)

(315)

但是,标准中的定义措辞是否定的,因此NULL可以获得怀疑的好处....

如您所见,在UNIQUE约束中避免使用NULL是个好主意.

讨论GROUP BY:

将NULL视为彼此相等,并形成自己的组.然后将每个组缩减为新结果表中的单行,以替换旧结果表.

这意味着对于GROUP BY子句,NULL = NULL不会计算为NULL,如在3VL中,但它计算为TRUE.

SQL标准令人困惑:

ORDER BY和NULL(329)

是否认为NULL的排序键值大于或小于非NULL值是实现定义的,但是......

...有两种SQL产品可以做到这一点.

1999年3月,Chris Farrar提出了他的一个开发人员的问题,这个问题使他检查了我认为我理解的SQL标准的一部分.克里斯发现一般理解与规范的实际措辞之间存在一些差异.

等等.我觉得Celko已经足够了.

SQL NULL上的CJ日期

CJ Date对于NULL更为激进:避免SQL中的NULL,句点.事实上,他的SQL和关系理论的第4章:如何编写准确的SQL代码标题为"没有重复,没有NULLS",子章节 "4.4什么是空的错误?" 和"4.5避免SQL中的空白"(请点击链接:感谢Google Books,您可以在线阅读一些页面).

关于SQL NULL的Fabian Pascal

数据库管理的实际问题 - 思维从业者的参考(没有在线摘录,抱歉):

10.3实际意义

10.3.1 SQL NULL

...... SQL存在3VL固有的问题以及许多怪癖,并发症,违反直觉和彻底错误[10,11]; 其中包括:

  • 聚合函数(例如,SUM(),AVG())忽略NULL(COUNT()除外).
  • 没有行的表上的标量表达式错误地计算为NULL,而不是0.
  • 表达式"NULL = NULL"的计算结果为NULL,但在SQL中实际上是无效的; 但ORDER BY将NULL视为相等(无论它们位于"常规"值之前还是之后,都留给DBMS供应商).
  • 表达式"x IS NOT NULL"不等于"NOT(x IS NULL)",如2VL中的情况.

...

所有商业实施的SQL方言都遵循这种3VL方法,因此,它们不仅能够解决这些问题,而且还会产生特定的实施问题,这些问题因产品而异.

  • "这就是我的观点:NULL,作为价值,是一个"奇怪的野兽"." - 那是因为`NULL`不是值. (4认同)
  • &gt;&gt;既然是12月,我们就以季节性为例。我在树下有两件礼物。现在,你告诉我是否有两个相同的东西。.....是的,你做了因为你得到了两件事,并且*就你现在而言*,就你目前的知识而言,它们对你来说是完全相同的 (2认同)
  • null = null应该为true。null是定义良好的值,可以“表示”一个“未知”值,但也可以“表示”一个值的“不存在”。开发人员应决定null代表什么,但是null本身绝对是一个值,并且null为null = null。任何其他实现都将带来灾难,因为您要将三元逻辑插入到本质上是布尔值的谓词中。我很高兴这已经成为SQL Server中永久的设置。关闭关闭关闭。 (2认同)

Ale*_*Dev 9

这里的答案似乎都来自 CS 的角度,所以我想从开发人员的角度添加一个。

对于开发人员来说,NULL 非常有用。这里的答案说 NULL 意味着未知,也许在 CS 理论中这是真的,不记得了,已经有一段时间了。但在实际开发中,至少根据我的经验,这种情况发生的概率约为 1%。其他 99% 用于值不是未知但已知不存在的情况。

例如:

  • Client.LastPurchase,对于新客户。这不是未知的,据了解他还没有进行购买。

  • 当使用带有每个层次结构映射的 ORM 时,某些值只是没有映射到某些类。

  • 在映射树结构时,根通常具有Parent = NULL

  • 还有很多...

我相信大多数开发人员在某个时候写过WHERE value = NULL,没有得到任何结果,这就是他们学习IS NULL语法的方式。看看这个问题和相关问题有多少票。

SQL 数据库是一种工具,应该以用户最容易理解的方式设计它们。

  • 每个人似乎都大喊“NULL 是未知的”,然后为这种行为辩护。是的,如果这是一个前提,那么 3VL 可能就是答案。但在我工作的几乎所有数据库中,NULL 意味着不存在。抱歉你的声音在荒野中消失了@AlexDev (2认同)

Eva*_*oll 8

仅仅因为你不知道两件事是什么,并不代表他们是平等的.如果你认为NULL你想到"NULL"(字符串)那么你可能想要一个不同的测试,如Postgresql的IS DISTINCT FROMANDIS NOT DISTINCT FROM

http://www.postgresql.org/docs/8.4/static/functions-comparison.html

表达式IS DISTINCT FROM表达式

表达式IS NOT DISTINCT FROM表达式

对于非空输入,IS DISTINCT FROM与<>运算符相同.但是,如果两个输入都为null,则返回false,如果只有一个输入为null,则返回true.类似地,对于非空输入,IS NOT DISTINCT FROM与=相同,但是当两个输入都为空时返回true,而当只有一个输入为null时返回false.因此,这些构造有效地表现为null是正常数据值,而不是"未知".


Mic*_*ker 8

也许它取决于,但我认为NULL=NULL评估NULL大多数操作与NULL作为操作数.


Mag*_*nus 6

technet 上,对空值的工作方式有一个很好的解释。

Null 表示未知。

因此布尔表达式

值=空

不计算为 false,计算为 null,但如果这是 where 子句的最终结果,则不返回任何内容。这是一种实用的方法,因为很难想象返回 null。

了解以下内容有趣且非常重要

如果在查询中我们有

where (value=@param Or @param is null) And id=@anotherParam
Run Code Online (Sandbox Code Playgroud)

  • 值=1
  • @param 为空
  • 编号=123
  • @anotherParam=123

然后

"value=@param" 计算结果为 null
"@param is null" 计算结果为 true
"id=@anotherParam" 计算结果为 true

所以要评估的表达式变成

(null 或 true) 和 true

我们可能会认为这里的“null 或 true”将被评估为 null,因此整个表达式变为 null 并且不会返回该行。

事实并非如此。为什么?

因为“null Or true”的计算结果为true,这是非常合乎逻辑的,因为如果Or运算符的一个操作数为true,那么无论另一个操作数的值如何,该操作都将返回true。因此,另一个操作数未知(空)并不重要。

所以我们终于有了 true=true ,因此该行将被返回。

注意:“null 或 true”的计算结果为真,“null And true”的计算结果为 null,逻辑清晰。

更新:
好的,为了使它完整,我也想在这里添加其余的内容,与上述内容相比,这很有趣。

“null 或 false”计算结果为 null,“null And false”计算结果为 false。:)

逻辑当然还是和以前一样不言而喻。


Pau*_*and 5

MSDN 有一篇关于空值和它们产生的三种状态逻辑的很好的描述性文章

简而言之,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
Run Code Online (Sandbox Code Playgroud)


one*_*hen 5

至少可以说,NULL 的概念是有问题的。Codd 在上下文中引入了关系模型和 NULL 的概念(并继续提出了不止一种 NULL!)然而,自 Codd 的原始著作以来,关系理论已经发展:他的一些提议已被放弃(例如主键)和其他人从未流行过(例如 theta 运算符)。在现代关系理论(真正的关系理论,我应该强调)中,NULL 根本不存在。见第三宣言。http://www.thethirdmanifesto.com/

SQL 语言存在向后兼容性的问题。NULL 进入了 SQL 并且我们被它困住了。可以说,NULL在 SQL 中的实现是有缺陷的(SQL Server 的实现由于它的ANSI_NULLS选项使事情变得更加复杂)。

我建议避免在基表中使用 NULLable 列。


虽然也许我不应该受到诱惑,但我只是想就NULLSQL 中的工作方式断言我自己的更正:

NULL=NULL评估为UNKNOWN

UNKNOWN 是一个逻辑值。

NULL 是一个数据值。

这很容易证明,例如

SELECT NULL = NULL

在 SQL Server 中正确生成错误。如果结果是一个数据值,那么我们希望看到NULL,因为这里的一些答案(错误地)表明我们会看到。

逻辑值UNKNOWN分别在 SQL DML 和 SQL DDL 中被区别对待。

在 SQL DML 中,UNKNOWN导致从结果集中删除行。

例如:

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);
Run Code Online (Sandbox Code Playgroud)

INSERT行成功,即使CHECK条件解析为NULL = NULL。这是在 SQL-92(“ANSI”)标准中定义的:

11.6 表约束定义

3)

若表约束为校验约束定义,则设SC为校验约束定义中直接包含的搜索条件,T为对应表约束描述符中包含的表名;表约束不满足当且仅当

存在(从 T WHERE NOT (SC) 中选择 *)

是真的。

仔细阅读一遍,遵循逻辑。

用简单的英语,我们上面的新行给出了关于存在UNKNOWN和允许通过的“怀疑的好处” 。

在 SQL DML 中,WHERE子句的规则更容易遵循:

搜索条件应用于 T 的每一行。 where 子句的结果是 T 中搜索条件结果为真的那些行的表。

在简单的英语中,评估为的行UNKNOWN将从结果集中删除。


arm*_*men 5

因为NULL意味着“未知值”并且两个未知值不能相等。

\n\n

因此,如果按照我们的逻辑NULLN\xc2\xb01 等于NULLN\xc2\xb02,那么我们必须以某种方式告诉:

\n\n
SELECT 1\nWHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中已知值-1N\xc2\xb01 等于-1N\xc2\xb02

\n