sql - 为什么 COALESCE 对单个列返回多个无效列名错误?

标签 sql sql-server function sql-server-2012 coalesce

当使用COALESCE编写SQL查询时,我注意到在特定情况下,它会针对单个无效列名引发多个错误。

如果我编写以下查询并尝试执行它,我会收到一条错误消息,简而言之,告诉我我是个白痴,并且该列不存在。

DECLARE @a TABLE (Column1 INT, Column2 INT)

-- This will return one error, complaining about NeverHeardOfIt
SELECT 
    COALESCE
      (
        Column1, 
        Column2, 
        NeverHeardOfIt
      ) 
FROM @a

Msg 207, Level 16, State 1, Line 8 Invalid column name 'NeverHeardOfIt'.

但是,如果我稍微更改查询以将无效列放在 COALESCE 语句的前面,我将收到两个错误:

DECLARE @a TABLE (Column1 INT, Column2 INT)

-- This will return two errors, both complaining about NeverHeardOfIt
SELECT 
    COALESCE
      (
        Column1, 
        NeverHeardOfIt, 
        Column2
      ) 
FROM @a 

Msg 207, Level 16, State 1, Line 7 Invalid column name 'NeverHeardOfIt'.

Msg 207, Level 16, State 1, Line 7 Invalid column name 'NeverHeardOfIt'.

我测试了几种不同的场景,似乎只有当我合并三个或更多列时才会发生这种情况,并且无效列不是最后一列。显然,“修复”这个问题很容易 - 不要引用无效列!但我很好奇为什么 COALESCE() 函数会两次抛出相同的错误。我能想到的最好的办法是,在底层,SQL 正在编写多个语句,大致如下:

If Column 1 is NULL, use NeverHeardOfIt

If NeverHeardOfIt IS NULL, use Column2

If Column2 is NULL ...

如果是这种情况,那么当我执行它时,我可以看到该函数如何/为什么会为其在幕后生成的每个“语句”返回错误。

有谁知道这是否正确,或者知道这会返回两个错误的其他原因?

最佳答案

我认为双重错误消息是一个错误,但很小。但是,原因是 coalesce() (还有 choose())实际上是简写。所以:

coalesce(a, b, c)

确实是:

(case when a is not null then a
      when b is not null then b
      else c
 end)

请注意,最后一个元素仅出现一次 - 因此当缺少的列位于末尾时,您只会收到一个错误。

这似乎是一个神秘的细节,但实际上很重要。例如,如果其中一个值是子查询(并且子查询的运行成本可能很高),那么它会在coalesce() 的计算中运行两次。当性能是一个问题并且一个或多个值是子查询时,即使我更喜欢 isnull() ,它在这些情况下表现更好。通常,我倾向于使用 ANSI 标准函数。

关于sql - 为什么 COALESCE 对单个列返回多个无效列名错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25408402/

相关文章:

php - 使用 Windows 帐户通过 PHP 连接到 SQL Server

sql - 在 SQL Server 执行之前修补过时的 SQL 查询?

sql - 需要为 Date 逻辑编写查询

php - 如何创建wordpress功能?

javascript - 如何提高这个JS函数的速度

c++ - 同一函数的两个版本(用于内联或 constexpr)

php - 有关数据库 sql 版本的信息

mysql - MySql中关系数据库设计的最佳方式

MYSQL:如何自动删除表中依赖于另一个表中的记录的行

mysql 使用带有动态表名的 SHOW CREATE TABLE