Estou escrevendo algum código para consultar alguns DMVs. Algumas das colunas podem ou não existir na DMV, dependendo da versão do SQL. Encontrei uma sugestão interessante online de como ignorar a verificação específica usando CROSS APPLY
.
A consulta abaixo é um exemplo de código para ler uma DMV para uma coluna potencialmente ausente. O código cria um valor padrão para a coluna e usa CROSS APPLY
para extrair a coluna real, se existir, da DMV.
A coluna que o código tenta extrair, BogusColumn, não existe. Eu esperaria que a consulta abaixo gere um erro sobre um nome de coluna inválido ... mas isso não ocorre. Retorna NULL sem erro.
Por que a cláusula CROSS APPLY abaixo NÃO resulta em um erro "nome inválido da coluna"?
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;
Se eu executar a consulta no CROSS APPLY
separadamente:
select BogusColumn from sys.dm_exec_sessions;
Recebo um erro esperado sobre um nome de coluna inválido:
Msg 207, Level 16, State 1, Line 9
Invalid column name 'BogusColumn'.
Se eu alterar o nome da coluna DMV para BogusColumn2 para torná-lo exclusivo, recebo o erro esperado do nome da coluna:
select a.BogusColumn1, b.BogusColumn2
from
(
select cast(null as int) as BogusColumn1
) a
cross apply
(
select BogusColumn2 from sys.dm_exec_sessions
) b
Eu testei esse comportamento nas versões do SQL 2012 ao SQL 2017, e o comportamento é consistente em todas as versões.
fonte
IF @MajorVersion >= @SQL2016 AND @MinorVersion >= @SQL2016SP1 BEGIN /* write and execute dynamic SQL, etc. */ END
Respostas:
BogusColumn é definido como uma coluna válida na 1ª consulta.
Quando aplicamos a aplicação cruzada, ela está usando a resolução da coluna da seguinte forma:
1. Procura a coluna 'BogusColumn' na 2ª consulta (dmv)
2. Se a coluna existir no dmv, ela será resolvida para o dmv
3 Se a coluna não existir no dmv, ela procurará essa coluna na consulta externa (a superior) e usará o valor fornecido lá.
Em outras palavras, quando a coluna falsa não estiver definida na exibição, a consulta final funcionará como:
Se estiver definido, a consulta será resolvida para:
fonte