使用COALESCE
编写SQL查询时,我注意到在特定情况下,它会为单个无效列名称抛出多个错误。
如果我编写以下查询并尝试执行它,我会收到一条错误消息,告诉我,简而言之,我是一个白痴,而且该列不存在。
DECLARE @a TABLE (Column1 INT, Column2 INT)
-- This will return one error, complaining about NeverHeardOfIt
SELECT
COALESCE
(
Column1,
Column2,
NeverHeardOfIt
)
FROM @a
消息207,级别16,状态1,行8无效的列名称 '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
消息207,级别16,状态1,行7无效的列名称 '从来没有听说过'。
消息207,级别16,状态1,行7无效列 名字'NeverHeardOfIt'。
我测试了几种不同的场景,似乎只有当我合并三列或更多列时才会发生这种情况,并且无效列不是最后一列。显然,“修复”这很容易 - 不要引用无效列!但我很想知道为什么COALESCE()
函数会两次抛出相同的错误。我能想到的最好的是,在引擎盖下,SQL正在编写多个语句,这些语句的内容如下:
如果第1列为NULL,请使用NeverHeardOfIt
如果NeverHeardOfIt为NULL,请使用Column2
如果Column2为NULL ...
如果是这种情况,那么当我执行它时,我可以看到函数如何/为什么会为它在幕后生成的每个'语句'返回错误。
有人知道这是否正确,或者知道另一个原因会导致两个错误吗?
答案 0 :(得分:3)
我会将双错误消息视为一个错误,但是非常小。但是,原因是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标准函数。