【问题标题】:Convert IS NULL to BIT将 IS NULL 转换为 BIT
【发布时间】:2016-08-21 16:21:22
【问题描述】:

这可能是一个非常基本的问题,但我只是在编写查询时遇到了它。

为什么 SQL Server 不能将NULL 的支票转换为BIT?我在想这样的事情:

DECLARE @someVariable INT = NULL;
-- Do something
SELECT CONVERT(BIT, (@someVariable IS NULL))

然后,预期结果将是 10

【问题讨论】:

  • 可以,但没有。例如,MySQL 可以并且确实做到了 ;-)
  • @ÁlvaroGonzález MySQL 包含 很多 非标准语句,甚至 break 的 SQL 逻辑。 IS 不能在条件表达式之外使用。它 不是 比较运算符。在空值逻辑中,任何与 NULL 的比较都是为空。 IS NULLIS NOT NULL 是唯一可以使用的条件运算符
  • @PanagiotisKanavos 我知道foo=NULLfoo IS NULL 不同(以及为什么)。但是,是否存在某些特定情况下 MySQL 实现会破坏某些东西?毕竟,当您使用WHERE deletion_date IS NULL 时,您最终会得到一个布尔不可为空的决定:显示该行 o not。
  • @ÁlvaroGonzález 是的,有很多。首先,BIT 不是布尔值,它只是一个数字。有一种不同的可选 BOOLEAN 类型,仅由 PostgreSQL 实现。其次,该演员确实打破了3VL。任何与 NULL 的比较都应返回 NULL,但任意转换不会。如果您想用1 替换NULL,只需使用NULLIFCOALESCE 之类的函数。最后,您可以强制转换 NULL 来表示特定类型的缺失值。 CAST(NULL as BIT) 允许并返回一个 NULL BIT

标签: sql-server tsql sql-server-2014


【解决方案1】:

使用case:

SELECT CONVERT(BIT, (CASE WHEN @someVariable IS NULL THEN 1 ELSE 0 END))

【讨论】:

  • 我知道这可以通过使用CASE 来实现。但我在问为什么 SQL Server 不知道如何处理@someVariable IS NULL
  • @diiN_ 我想我们都认为你在寻求一种方法来做到这一点。程序根本不够聪明,无法完成尚未编码的事情。
  • @ÁlvaroGonzález 有很多方法可以得到想要的结果。我只是不明白为什么不能像我尝试的那样使用它。
  • @ÁlvaroGonzález 不是的情况。您误解了IS NULL 在 SQL(该语言)中的作用。你不能在CASEWHERE之外使用它
  • @diiN_ 这就是 SQL 的工作原理(不仅仅是 SQL Server),它实际上是有道理的。与 C/C#/Java 不同,SQL 中的值可以 丢失,即 NULL。 NULL 不只是另一个值,它意味着无法与该值进行 any 有意义的比较,甚至无法与 NULL 进行比较。因此,将IS NULL 视为布尔表达式是没有意义的。
【解决方案2】:

在 SQL 语言中,NULL被视为数据值。它们代表缺失/未知状态。引用Wikipedia's article on SQL NULL:

SQL null 是一个状态(未知)而不是一个值。这种用法与大多数编程语言完全不同,其中 null 表示未分配给特定实例。

这意味着与UNKNOWN 值的任何比较 只能是UNKNOWN 本身。即使比较两个 NULL 也不能返回 true:如果两个值都是 unknown,我们怎么能说它们相等或不相等呢?

IS NULLIS NOT NULL 是可用于条件表达式的谓词。这意味着它们自己不返回值。因此,它们不能被“强制转换”为 bit 或被视为布尔值。

在将任何内容与 Null 进行比较时,基本 SQL 比较运算符总是返回 Unknown,因此 SQL 标准提供了两个特殊的 Null 特定比较谓词。 IS NULL 和 IS NOT NULL 谓词(使用后缀语法)测试数据是否为 ​​Null。

处理空值的任何其他方式都是特定于供应商的扩展。

最后,BIT 不是布尔类型,它只是一个单位数字。 SQL 1999 中引入了可选的BOOLEAN 类型,但只有PostgreSQL 正确实现了它,即具有TRUEFALSEUNKNOWN 值。

没有BOOLEAN 类型,您无法真正计算A AND Bx IS NULL 等条件表达式的结果。您只能使用 NULLIFCOALESCE 之类的函数将 NULL 值替换为其他值。

【讨论】:

  • 很好的解释。我可以添加一个后续问题吗?如果最初的问题是关于 SELECT CONVERT(BIT, (@someVariable=123))(即不涉及 NULL),您会在目前所说的内容中添加任何其他内容吗?
  • @ÁlvaroGonzález no,因为 1) 这是无效的语法 2) 这是演员表中的 assignment 还是尝试比较?和 3) 这应该是一个单独的问题,对于 CAST 的有效表达式以及标准和供应商实施之间的差异,以及最后是否可以在 SQL 中返回值,这应该是一个单独的问题。
  • 我完全误解了这个问题,因为我一直认为这完全是关于语法的。没关系...感谢您的出色回答。
  • ISNULL 不等同于 NULLIF,它是等同于 COALESCE 的 sqlserver,但限制只能允许两个参数。
  • @RaulSebastian 感谢您的反对。问题虽然不是关于 NULLIF 而是关于如何处理 NULL 以及为什么 IS NULL 不返回值
【解决方案3】:

不是直接投射

select cast(isnull(@null,1) as bit)

【讨论】:

    【解决方案4】:

    或者使用IIF(比CASE更易读):

    CONVERT(BIT, IIF(@x IS NULL, 0, 1))

    【讨论】:

      猜你喜欢
      • 2013-09-25
      • 2022-12-10
      • 1970-01-01
      • 2023-03-04
      • 2020-08-06
      • 1970-01-01
      • 2016-10-30
      • 2012-05-19
      • 2016-06-25
      相关资源
      最近更新 更多