【问题标题】:Comparisons with NULLs in SQL与 SQL 中的 NULL 比较
【发布时间】:2011-11-14 02:29:36
【问题描述】:

ANSI-92 SQL 要求与 NULL 的比较结果为“假”,例如:

SELECT * FROM table WHERE field = NULL
SELECT * FROM table WHERE field != NULL

两者都不会返回任何行,因为 NULL 无法像那样进行比较。相反,必须使用谓词IS NULLIS NOT NULL

SELECT * FROM table WHERE field IS NULL
SELECT * FROM table WHERE field IS NOT NULL

研究表明,Oracle 1、PostgreSQL、MySQL 和 SQLite 都支持 ANSI 语法。将 DB2 和 Firebird 添加到该列表中。

除了关闭ANSI_NULLS 的SQL Server 之外,还有哪些其他RDBMS 支持非ANSI 语法?

1 整个空字符串 = NULL 尽管一团糟。

【问题讨论】:

  • Oracle(此处为 11g)完全按照您在两种情况下的描述。

标签: sql null ansi-sql


【解决方案1】:

对于它的价值,将某些东西与 NULL 进行比较并非严格来说是错误的,它是 未知的。而且,NOTunknown 还是未知数。

ANSI SQL-99 定义了一个谓词IS [NOT] DISTINCT FROM。这允许您在comarisons 中混合空值和非空值,并始终得到真或假。 Null 与 null 以这种方式比较为真,否则任何非 null 与 null 比较为假。因此,否定的工作方式可能与您预期的一样。

PostgreSQL、IBM DB2 和 Firebird 确​​实支持 IS [NOT] DISTINCT FROM

MySQL 有一个类似的 null 安全比较运算符 <=>,如果操作数相同则返回 true,如果它们不同则返回 false。

Oracle 拥有最艰难的道路。您必须使用NVL() 或布尔表达式来发挥创意:

WHERE a = b OR (a IS NULL AND b IS NULL)

呸。

【讨论】:

  • 字里行间是没有标准的方法来禁用标准行为。
  • @Daniel 我根本不是在寻找标准方法;只是任何方式(如SQL Server的SET ANSI_NULLS OFF
  • 我不知道其他 RDBMS 中有类似的配置选项。我只是想建议其他解决方案来进行 null 安全比较。
  • 如果你使用比尔的解决方案,你会以标准的方式得到你想要的行为。如果您改为找到供应商特定的禁用标准行为的方法并这样做,您将获得双重不可移植的代码:一次是依赖于供应商扩展,另一次是在所有语句中使用错误类型的比较。强烈不推荐。
  • afaik,distinct from 谓词未在 LUW DB2 中公开。这就是很多人看到的db2的味道。
【解决方案2】:

Here 很好地比较了 SQLite、PostgreSQL、Oracle、Informix、DB2、MS-SQL、OCELOT、MySQL 3.23.41、MySQL 4.0.16、Firebird、SQL Anywhere 和 Borland Interbase 中的 null 处理

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多