How to Short-Circuit SQL Where Clause

前端 未结 5 1632
自闭症患者
自闭症患者 2020-12-10 16:17

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

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

SELECT  * FROM TABLE_1 
WHERE (ISDATE(@queryWord) =         


        
相关标签:
5条回答
  • 2020-12-10 16:30

    Why not do a CASE in the WHERE condition?

    DECLARE @tester TABLE (
        theDate DATE,
        theValue INT
        )
    
    INSERT INTO @tester VALUES ('2013-10-17', 35)
    INSERT INTO @tester VALUES ('2013-10-16', 50)
    INSERT INTO @tester VALUES ('2013-10-15', 2)
    
    declare @queryWord as nvarchar(20) = 'asdas'
    SELECT  *
    FROM @tester
    WHERE theDate =
        CASE
            WHEN ISDATE(@queryWord) = 1 THEN CONVERT(Date, @queryWord)
            ELSE theDate
        END
    
    SET @queryWord = '2013-10-17'
    SELECT  *
    FROM @tester
    WHERE theDate =
        CASE
            WHEN ISDATE(@queryWord) = 1 THEN CONVERT(Date, @queryWord)
            ELSE theDate
        END
    
    0 讨论(0)
  • 2020-12-10 16:36

    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.

    0 讨论(0)
  • 2020-12-10 16:37

    It can be "simulated" with a CASE statement. But you have to make the first condition giving a TRUE value to avoid checking of the 2nd condition :

    declare @queryWord as nvarchar(20) = 'asdas'
    
    SELECT  * 
    FROM TABLE_1
    WHERE (CASE 
           WHEN ISDATE(@queryWord) = 0 THEN 0 
           WHEN TABLE_1.INIT_DATE = CONVERT(Date, @queryWord) THEN 1
           ELSE 0 END) = 1
    
    0 讨论(0)
  • 2020-12-10 16:45

    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.

    0 讨论(0)
  • 2020-12-10 16:46

    There is no defined evaluation order in a SQL statement -- except in the case of case expressions, and even there the order isn't so much defined as the result guaranteed. The conditions in your where clause could theoretically be done in parallel or alternating order.

    Case expressions differ not by having a defined order, but by having a guaranteed result. IOW, case when 1=1 then 0 When longrunningfunction() = 1 then 2 end is guaranteed to return zero, but there is no promise not to run the longrunningfunction.

    0 讨论(0)
提交回复
热议问题