为什么NULL字段被称为相等?

时间:2011-10-10 20:08:23

标签: advantage-database-server

我正在编写触发器来检测数据库中字段的变化,看来我必须做一些非常讨厌的事情,比如

(SELECT SalesPrice FROM __old) <> (SELECT SalesPrice FROM __new)
or ((SELECT SalesPrice FROM __old) IS NULL and (SELECT SalesPrice FROM __new) IS NOT NULL)
or ((SELECT SalesPrice FROM __old) IS NOT NULL and (SELECT SalesPrice FROM __new) IS NULL)

而不仅仅是

(SELECT SalesPrice FROM __old) <> (SELECT SalesPrice FROM __new)

准确检测某个字段是否发生了变化。

我错过了什么,或者Advantage是否有效地声称NULL ==任何值?这种行为有充分的理由吗?这是SQL定义中的一些奇怪的东西吗?有没有更简洁的方法,不会做3次检查而不是一次?

2 个答案:

答案 0 :(得分:3)

不幸的是,SQL如何使用NULL值。 NULL不等于任何东西,它是UNKNOWN。例如, somevalue == NULL - &gt;未知 somevalue&lt;&gt; NULL - &gt;未知

因此,它永远不会通过“真实”检查 Null Values - Wikipedia

有几种选择: A)不允许空值(我建议将其与默认值组合) B)使用IFNULL将字段设置为某个值,例如

(SELECT IFNULL(SalesPrice, -9999) FROM __OLD) <> (SELECT IFNULL(SalesPrice, -9999) FROM __NEW)

但我不知道我是否一定喜欢这个,因为必须选择一个无效的值。

答案 1 :(得分:1)

在SQL中,除了IS [NOT] NULL表达式之外,NULL不会与任何内容进行比较。如果我理解你的问题是正确的,那么这里的问题是NULL必须等于NULL。如果是这种情况,可以将检查简化为:

( SELECT CASE WHEN n.SalesPrice IS NULL and o.SalePrice IS NULL THEN TRUE
         ELSE n.SalesPrice = o.SalesPrice END
  FROM __old o, __new n )