为什么CROSS APPLY * not *在此查询中没有得到无效的列错误?

Pau*_*ams 7 t-sql sql-server cross-apply

我正在编写一些代码来查询某些DMV。根据SQL版本,DMV中某些列可能存在也可能不存在。我在网上找到了一个有趣的建议,如何跳过使用的特定检查CROSS APPLY

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

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

为什么下面的CROSS APPLY子句不会导致“无效的列名”错误?

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;
Run Code Online (Sandbox Code Playgroud)

如果我分别运行查询CROSS APPLY

select BogusColumn from sys.dm_exec_sessions;
Run Code Online (Sandbox Code Playgroud)

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

Msg 207, Level 16, State 1, Line 9
Invalid column name 'BogusColumn'.
Run Code Online (Sandbox Code Playgroud)

如果我将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
Run Code Online (Sandbox Code Playgroud)

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

Pio*_*otr 7

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;
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)