当使用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/