一部の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;
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のバージョンでこの動作をテストしましたが、動作はすべてのバージョンで一貫しています。
IF @MajorVersion >= @SQL2016 AND @MinorVersion >= @SQL2016SP1 BEGIN /* write and execute dynamic SQL, etc. */ END