简体   繁体   中英

SQL Server order by expression

While watching Troy Hunt's fantastic course on SQLi , I've noticed that he ends up using this strategy to see if a table has a specific column:

select * from TableA order by (select top 1 some_column from TableB) desc

This expression will get executed by SQL Server, but what will it do for the order by clause? I've seen expressions being used with order by before (case when then else end), but I'm really curious to understand how SQL can process the previous query without any errors...

EDIT : Giving more info because it seems like my initial post was not clear enough:

  1. I know this is not the best strategy for getting table or column name though SQLi (that's not what I'm asking)
  2. I'm not interested in knowing how to protect against this (I know how to do that already)
  3. I know that sorting by a constant value doesn't make sense (though it allows you to run these types of "boolean queries")
  4. What t I really want to know is why it works.

So, going back to the docs, the order by clause expects an order_by_expression , which is described as:

Specifies a column or expression on which to sort the query result set. A sort column can be specified as a name or column alias, or a nonnegative integer representing the position of the column in the select list.

According to the docs , an expression is:

Is a combination of symbols and operators that the SQL Server Database Engine evaluates to obtain a single data value. Simple expressions can be a single constant, variable, column, or scalar function. Operators can be used to join two or more simple expressions into a complex expression.

As @SMor demonstrated, the query does run if you replace the order by select expression with a simple select 'A' :

select * from TableA order by (select 'A') desc

But this does not work:

select * from TableA order by 'A' desc

So, the question is: why is select 'A' accepted by SQL Server in the order by clause? Doesn't it produce a constant too? Since a constant is an expression and taking into account the definition for the order by clause, shouldn't it thrown an error in both cases?

Thanks.

The use of (select top 1 some_column from TableB) is an example of a scalar subquery . This is a subquery that returns exactly one column and at most one row. It can be used anywhere a literal value can be used -- and perhaps in some other places as well. Apparently, it can be used in an order by , even though SQL Server does not allow a literal value for order by .

The most common type of scalar subquery is a correlated subquery , which has a where clause that connects the subquery to the outer query. This is not an example of a scalar subquery.

In fact, this is not an example of anything useful as far as I can tell. It has one major shortcoming, which is the use of top without order by . The value returned by the subquery is indeterminate. That seems like a bad practice, and particularly bad if you are trying to teach people SQL.

And, it is probably going to be evaluated once. So the subquery would return a constant value and would not contribute much to a meaningful ordering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM