【问题标题】:MyNullableCol <> 'MyValue' Doesn't Includes Rows where MyNullableCol IS NULLMyNullableCol <> 'MyValue' 不包括 MyNullableCol 为 NULL 的行
【发布时间】:2010-01-14 08:23:04
【问题描述】:

今天我发现一个奇怪的问题是我有一个可以为空列的表,我尝试使用以下查询

选择 * ID, 我的NCol, FROM dbo.[MyTable] WHERE MyNCol 'MyValue'

并期望它返回字段 MyNCol 中没有“MyValue”值的所有行。但它没有返回上面指定的列(MyNCol)中所有包含 NULL 的行。 所以我必须将我的查询重写为

选择 * ID, 我的NCol, FROM dbo.[MyTable] WHERE MyNCol 'MyValue' OR MyNCol 为空

现在我的问题是为什么第一个查询不足以执行我想要的。 :(

问候 穆巴沙尔

【问题讨论】:

    标签: sql-server sql-server-2008 nullable


    【解决方案1】:

    查看“ANSI NULL”的行为。

    通常,NULL != NULL。您可以通过更改数据库上启用 ANSI NULLS 的属性来更改此行为,但这对列存储和查询执行具有广泛的影响。或者,您可以在 SQL 脚本中使用 SET ANSI_NULLS 语句。

    SQL Server 2008 的 MSDN 文档在这里:
    SET ANSI_NULLS (Transact-SQL)

    请特别注意如何执行比较的细节 - 即使将 ANSI_NULLS 设置为 OFF,列与列的比较也可能不会像您预期的那样运行。最佳做法是始终使用 IS NULL 和 IS NOT NULL。

    【讨论】:

      【解决方案2】:

      不能对空值执行等式运算符。在 SQL 2000 中,您可以检查 null = null,但是在 2005 年,这种情况发生了变化。

      【讨论】:

        【解决方案3】:

        NULL = 未知。因此,您既不能说 MyNCol = 'My Value' 也不能说 MyNCol 'My Value' - 两者都评估为 UNKNOWN(就像 'foo' + MyNCol 仍将变为 NULL)。您发布的解决方法的替代方法是:

        WHERE COALESCE(MyNCol, 'Not my Value') <> 'My Value';
        

        这将包括 NULL 列,因为比较变为错误而不是未知。我不喜欢这个选项,因为它依赖于比较中的一些魔法值,即使只有当列为 NULL 时才会提供魔法值。

        【讨论】:

        • 感谢您的回答,是的,您是对的,我不这么认为。但是您认为我的第二个查询更好还是您所说的方式?。
        • 哪种方式对您或您的团队更有意义?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-09
        • 1970-01-01
        • 2017-10-03
        • 1970-01-01
        • 2018-10-25
        • 2019-01-13
        相关资源
        最近更新 更多