Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Short-Circuit SQL Where Clause

I am trying to perform the following query in SQL server:

declare @queryWord as nvarchar(20) = 'asdas'

SELECT  * FROM TABLE_1 
WHERE (ISDATE(@queryWord) = 1) 
AND TABLE_1.INIT_DATE = CONVERT(Date, @queryWord)

This obviously causes an error because 'asdas' cannot be converted to Date. Although, I was expecting a different behavior. That is, because ISDATE(@queryWord) = 1 is false, I was expecting SQL to not check the second condition, but apparently, it does.

I know there are some other ways to perform this query but this is not my question. I wonder if there is some way to do not check the second condition is the first one does not satisfy. I am curious because I thought that SQL already did this.

like image 742
nachovall Avatar asked Oct 17 '13 14:10

nachovall


People also ask

Does SQL where short circuit?

SQL Server does short-circuit sometimes, but the rules are complex, undocumented, and subject to change at any time. It seems unwise to depend on such things.

How do you write a WHERE clause in SQL?

You write the WHERE clause like this: SELECT column1, column2... FROM table_name WHERE condition; Note that here I've written it using the SELECT statement, but its use is not limited to SELECT .

Is it OK to write WHERE and HAVING clause in a single query?

A query can contain both a WHERE clause and a HAVING clause. In that case: The WHERE clause is applied first to the individual rows in the tables or table-valued objects in the Diagram pane. Only the rows that meet the conditions in the WHERE clause are grouped.

How does the WHERE clause work in SQL?

In a SQL statement, the WHERE clause specifies criteria that field values must meet for the records that contain the values to be included in the query results.


2 Answers

SQL Server does not do short-circuiting (nor should it).

If you need it to not try something under some circumstances, you need to force that in the way that you write your query.

For this query the easiest fix would be to use a CASE expression in your WHERE clause.

declare @queryWord as nvarchar(20) = 'asdas'

SELECT  * FROM TABLE_1 
WHERE TABLE_1.INIT_DATE = (CASE WHEN ISDATE(@queryWord) = 1 
                                THEN CONVERT(Date, @queryWord)
                           ELSE NULL  END)

Off-hand, CASE and query-nesting are the only two supported ways that I can think of to force an order of evaluation for dependent conditions in SQL.

like image 189
RBarryYoung Avatar answered Sep 30 '22 00:09

RBarryYoung


I Guess you could do it in 2 passes:

declare @queryWord as nvarchar(20) = 'asdas'


    select
    *
    from
    (
    SELECT  * FROM TABLE_1 
    WHERE (ISDATE(@queryWord) = 1) ) t1
    where t1.INIT_DATE = CONVERT(Date, @queryWord)

So your inner query runs the first test and the outer query the second. In a single query, I don't believe there is any way to force any order of evaluating conditions.

like image 24
Andrew Avatar answered Sep 29 '22 23:09

Andrew