Estoy escribiendo un código para consultar algunos DMV. Algunas de las columnas pueden o no existir en el DMV dependiendo de la versión de SQL. Encontré una sugerencia interesante en línea sobre cómo omitir comprobaciones específicas usando CROSS APPLY
.
La consulta a continuación es un ejemplo de código para leer un DMV para una columna potencialmente faltante. El código crea un valor predeterminado para la columna y lo utiliza CROSS APPLY
para extraer la columna real, si existe, del DMV.
La columna que el código intenta extraer, BogusColumn, no existe. Esperaría que la consulta a continuación genere un error sobre un nombre de columna no válido ... pero no lo hace. Devuelve NULL sin error.
¿Por qué la cláusula CROSS APPLY a continuación NO da como resultado un error de "nombre de columna no válido"?
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;
Si ejecuto la consulta por CROSS APPLY
separado:
select BogusColumn from sys.dm_exec_sessions;
Recibo un error esperado sobre un nombre de columna no válido:
Msg 207, Level 16, State 1, Line 9
Invalid column name 'BogusColumn'.
Si cambio el nombre de la columna DMV a BogusColumn2 para que sea único, obtengo el error de nombre de columna esperado:
select a.BogusColumn1, b.BogusColumn2
from
(
select cast(null as int) as BogusColumn1
) a
cross apply
(
select BogusColumn2 from sys.dm_exec_sessions
) b
He probado este comportamiento en las versiones de SQL 2012 hasta SQL 2017, y el comportamiento es consistente en todas las versiones.
fuente
IF @MajorVersion >= @SQL2016 AND @MinorVersion >= @SQL2016SP1 BEGIN /* write and execute dynamic SQL, etc. */ END
Respuestas:
BogusColumn se define como una columna válida en la primera consulta.
Cuando aplicamos la aplicación cruzada, se utiliza la resolución de columna de la siguiente manera:
1. Busca la columna 'BogusColumn' en la segunda consulta (dmv)
2. Si la columna existe en el dmv, se resolverá en el dmv
3 Si la columna no existe en el dmv, buscará esta columna en la consulta externa (la superior) y usará el valor proporcionado allí.
En otras palabras, cuando la columna falsa no está definida en la vista, la consulta final funcionará como:
Si está definido, la consulta se resolverá en:
fuente