为什么 CROSS APPLY *not* 在此查询中出现无效列错误?

Why does CROSS APPLY *not* get an invalid column error in this query?

我正在编写一些代码来查询一些 DMV。根据 SQL 版本,DMV 中可能存在或不存在某些列。我在网上发现了一个有趣的建议,如何使用 CROSS APPLY.

跳过特定检查

下面的查询是一个代码示例,用于读取可能缺失的列的 DMV。该代码为该列创建一个默认值,并使用 CROSS APPLY 从 DMV 中提取实际列(如果存在)。

代码尝试提取的列 BogusColumn 不存在。我希望下面的查询会生成有关无效列名的错误...但事实并非如此。它 returns NULL 没有错误。

为什么下面的 CROSS APPLY 子句不会导致 "invalid column name" 错误?

declare @x int
select @x = b.BogusColumn
from
(
    select cast(null as int) as BogusColumn
) a
cross apply
(
    select BogusColumn from sys.dm_exec_sessions
) b;
select @x;

如果我运行在CROSS APPLY中单独查询:

select BogusColumn from sys.dm_exec_sessions;

我收到关于无效列名称的预期错误:

Msg 207, Level 16, State 1, Line 9
Invalid column name 'BogusColumn'.

如果我将 DMV 列名称更改为 BogusColumn2 以使其唯一,我会收到预期的列名称错误:

select a.BogusColumn1, b.BogusColumn2
from
(
    select cast(null as int) as BogusColumn1
) a
cross apply
(
    select BogusColumn2 from sys.dm_exec_sessions
) b

我已经在 SQL 2012 到 SQL 2017 的版本上测试了此行为,并且该行为在所有版本中都是一致的。

BogusColumn 被定义为第一个查询中的有效列。

当我们应用交叉应用时,它使用列分辨率如下:
1. 它在第二个查询 (dmv)
中查找列 'BogusColumn' 2.如果dmv中存在该列,则解析为dmv
3. 如果 dmv 中不存在该列,它将在外部查询(最上面的)中查找该列并使用那里提供的值。

换句话说,当视图中未定义伪列时,最终查询将作为:

select * from
(
    select cast(null as int) as BogusColumn
) a
cross apply
(
    select a.BogusColumn AS BogusColumn from sys.dm_exec_sessions
) b;

如果已定义,查询将解析为:

select * from
(
    select cast(null as int) as BogusColumn
) a
cross apply
(
    select s.BogusColumn AS BogusColumn from sys.dm_exec_sessions as s
) b;