Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL: Cancel 'where' on null parameter

Tags:

sql

tsql

This may be obvious but I'm getting very confused.

I have an SQL query with a where clause (where in with a list of parameters). If all of these parameters are null, I need the SQL to ignore the where clause and retrieve all the records. Is this easy to do in SQL? I know one way around it is to just remove the where clause using code if the parameters are null.

like image 745
Chris Avatar asked Jan 20 '11 10:01

Chris


People also ask

How to check if parameter is NULL in SQL?

The is_null() function checks whether a variable is NULL or not. This function returns true (1) if the variable is NULL, otherwise it returns false/nothing.

When parameter is NULL?

When the parameter has no value, SQL interprets it as null in your code. Null means no value. You can fix this problem by adding a code to fix the null case. There are 3 ways to resolve this problem: you can either coalesce the null value or add a logic to execute another operation.

Can you use coalesce in where clause?

Because the COALESCE is an expression, you can use it in any clause that accepts an expression such as SELECT , WHERE , GROUP BY , and HAVING .

Can we pass NULL as a parameter in SQL?

In SQL, null acts a bit differently to other values - you can't just evaluate things as being = null, as this doesn't really work, you need to use "myColumn is null" instead. In your case, when you need to match either a value or a null, you might need to use a case statement in your where clause.


2 Answers

You could try do something like this:

select *
from foo
where (@parameter1 is null AND @parameter2 is null)
OR  (@parameter1 = 'value1'
    AND
    @parameter2 = 'value2')

Offcourse it needs a bit of tuning in your own query, but now you will check if the parameters are null or do your original where-clause.

like image 182
Jan_V Avatar answered Sep 18 '22 11:09

Jan_V


The most performant way is to not include the WHERE clause at all if that's an option for you.

You often see tricks such as WHERE X=@X OR @X IS NULL used but these can lead to sub optimal plans and unnecessary table scans in the event you are passing a specific value for @X

Edit:

As this answer seems to have met with some unexpected scepticism...

create table #t
(
id varchar(5) primary key /*varchar to test LIKE without causing any casts*/
)

INSERT INTO #t
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM sys.all_columns


SET STATISTICS IO ON
/*Test the equals */

EXEC sp_executesql N'
SELECT * 
FROM #t
WHERE (@id IS NULL OR id = @id)', N'@id varchar(5)', @id='1'

/*Is `LIKE` any better? */

EXEC sp_executesql N'
SELECT * 
FROM #t
WHERE (@id IS NULL OR id LIKE @id)', N'@id varchar(5)', @id='1'

/*What should the plan look like? */

EXEC sp_executesql N'
SELECT * 
FROM #t
WHERE (id = @id)', N'@id varchar(5)', @id='1'

DROP TABLE #t

Execution Plans

like image 22
Martin Smith Avatar answered Sep 18 '22 11:09

Martin Smith