Equivalent to VB AndAlso in SQL?
Asked Answered
J

5

5

Is there an equivalent to VB's AndAlso/OrElse and C#'s &&/|| in SQL (SQL Server 2005). I am running a select query similar to the following:

SELECT a,b,c,d
FROM table1
WHERE 
(@a IS NULL OR a = @a)
AND (@b IS NULL OR b = @b)
AND (@c IS NULL OR c = @c)
AND (@d IS NULL OR d = @d)

For example, if the "@a" parameter passed in as NULL there is no point in evaluating the 2nd part of the WHERE clause (a = @a). Is there a way to avoid this either by using special syntax or rewriting the query?

Thanks, James.

Janusfaced answered 30/10, 2009 at 11:18 Comment(0)
P
6

The only way to guarantee the order of evaluation is to use CASE

WHERE
   CASE
      WHEN @a IS NULL THEN 1
      WHEN a = @a THEN 1
      ELSE 0
   END = 1
   AND /*repeat*/

In my experience this is usually slower then just letting the DB engine sort it out.

TerrorAustralis's answer is usually the best option for non-nullable columns

Proliferous answered 18/7, 2010 at 12:44 Comment(1)
Though slower in general, you might have a complex expression as the second one where the case is faster, and in special cases the second part might not even evaluate (see the example by MikeMuffinMan), so in some cased the andalso/orelse approach with a CASE is a must.Privateer
U
3

Try this:

AND a = ISNULL(@a,a)

This function looks at @a. If it is not null it equates the expression

AND a = @a

If it is null it equates the expression

AND a = a 

(Since this is always true, it replaces the @b is null statement)

Unrest answered 30/10, 2009 at 13:0 Comment(1)
One should be careful with this approach, depending on the actual query. An IsNull on a field could prevent it from using an index. Here it is on a variable so might work here, but in general be careful. SQL can use index efficiently for a "b is null or b=@b", but not for a "Isnull(b,@b)=@b".Privateer
U
2

The query engine will take care of this for you. Your query, as written, is fine. All operators will "short circuit" if they can.

Unjaundiced answered 30/10, 2009 at 11:24 Comment(1)
No they won't. You have no idea what order they will be evaluated in SQL.Proliferous
B
0

Another way is to do:

IF (@a > 0) IF (@a = 5)
BEGIN

END

Another if after the condition will do an "AndAlso" logic.

I want to emphesise that this is just a short way to write:

IF (@a > 0) 
     IF (@a = 5)
     BEGIN

     END
Balancer answered 2/2, 2014 at 15:6 Comment(1)
Unfortunately we only have he CASE not the IF in a WHERE clause. But in a statement block you are right.Privateer
H
0

Take this example:

SELECT * FROM Orders
WHERE orderId LIKE '%[0-9]%' 
AND dbo.JobIsPending(OrderId) = 1 

Orders.OrderId is varchar(25)

dbo.JobIsPending(OrderId) UDF with int parameter

No short circuit is made as the conversion fails in dbo.JobIsPending(OrderId) when Orders.OrderId NOT LIKE '%[0-9]%'

tested on SQL Server 2008 R2

Harriman answered 15/2, 2014 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.