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的版本上测试了此行为,并且该行为在所有版本中都是一致的。
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)