Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does CROSS APPLY *not* get an invalid column error in this query?

I am writing some code to query some DMVs. Some of the columns may or may not exist in the DMV depending on SQL version. I found an interesting suggestion online how to skip specific checking using CROSS APPLY.

The query below is an example of code to read a DMV for a potentially missing column. The code creates a default value for the column and uses CROSS APPLY to extract the actual column, if it exists, from the DMV.

The column the code tries to extract, BogusColumn, does not exist. I would expect the query below to generate an error about an invalid column name... but it does not. It returns NULL without error.

Why does the CROSS APPLY clause below NOT result in an "invalid column name" error?

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;

If I run the query in the CROSS APPLY separately:

select BogusColumn from sys.dm_exec_sessions;

I get an expected error about an invalid column name:

Msg 207, Level 16, State 1, Line 9
Invalid column name 'BogusColumn'.

If I change the DMV column name to BogusColumn2 to make it unique, I get the expected column name error:

select a.BogusColumn1, b.BogusColumn2
from
(
    select cast(null as int) as BogusColumn1
) a
cross apply
(
    select BogusColumn2 from sys.dm_exec_sessions
) b

I have tested this behavior on versions of SQL 2012 through SQL 2017, and the behavior is consistent across all versions.

like image 662
Paul Williams Avatar asked Nov 20 '19 23:11

Paul Williams


People also ask

Why do I keep getting invalid column name in SQL?

An invalid column name error in SQL means that the column name violates the conditions of the column name. If you reference an object that does not exist in the table or the name exists, but you did not reference it correctly, you will get this error.

How can you fix an ambiguous column reference error?

You may see an error that says something like Column 'id' in field list is ambiguous . This error means that there is a field name that is present in more than one table, so it needs to be scoped with the table name to avoid ambiguity: using orders.id instead of just id will resolve the issue.

What is the cross apply in SQL?

The CROSS APPLY operator returns only those rows from the left table expression (in its final output) if it matches with the right table expression. Thus, the CROSS APPLY is similar to an INNER JOIN, or, more precisely, like a CROSS JOIN with a correlated sub-query with an implicit join condition of 1=1.

How do you fix an ambiguous error in SQL?

The SQL Machine is confused as to which “Name” out of the two tables you are referring to. It is ambiguous — not clear. To clarify this, add the alias of either or both TABLE1 or TABLE2 to the columns having the same name. You will notice above, the alias of TABLE1 is A while that of TABLE2 is B.


1 Answers

BogusColumn is defined as a valid column in the 1st query.

When we are applying cross apply, it is using column resolution as follow:
1. It looks for the column 'BogusColumn' in the 2nd query (dmv)
2. If the column exists in the dmv, it will be resolved to the dmv
3. If the column do not exists in the dmv, it will look for this column in the outer query (the top one) and use value provided there.

In other words when bogus column is not defined in the view the final query will work as:

select * from
(
    select cast(null as int) as BogusColumn
) a
cross apply
(
    select a.BogusColumn AS BogusColumn from sys.dm_exec_sessions
) b;

If it is defined, query will resolve to:

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;
like image 134
Piotr Palka Avatar answered Oct 24 '22 13:10

Piotr Palka