Best query approach when using NULLABLE columns in parameterized SELECT

Posted on 2007-11-22
Last Modified: 2010-04-21
I'm just past the newbie stage of SQL Server with respect to learning more than how to build an ad-hoc query using user input.  Several variables play into my question.

1) I recognize the need to parameterize my queries to protect against SQL injection, among other things.  

2) I give my customer the ability to provide the values for 1 or more columns - some of which are NULLABLE.

3) I have been using the FilterExpression with my adhoc queries but have been dissatisfied with the inability to discern the actual number of filtered items. (Plus - is it performant???)

4) I recognize that "unnamed" ad-hoc queries are very likely the least performant of all queries, and I have been reading up on stored procedures, since they "sound" like a good thing.

5)  I'm trying to determine the overall best approach to having a "named" (aka performant) query, parameterized, which accounts for the possibility that one of my optional parameters may be on a NULLABLE column - in which case if it happens to be NULL when I specify NULL for the parameter value to indicate that I'm not querying on it this time - that the row will still be selected.

6) I started converting my ad-hoc query into a parameterized stored procedure.  All went well enough until I noticed I was not getting all of the rows due to this NULLABLE column that contained a NULL value.

7) ISNULL does not solve the problem.

8) In searching the internet about this problem, I've read article after article about the pros and cons of Dynamic SQL vs stored procedures and coalese vs ISNULL.    It appears to be a hotly debated topic to put it mildly. To be honest, the Monty Python "It's Just a Flesh Wound scene" comes to mind when I read the articles and the rebuttals.

(And now to my question - at the risk of getting my own arms or legs cut off... )  :

I really need expert advice on the best approach to how to make a performant, parameterized query that accepts optional parameters on columns that may be NULLABLE.   Many many thanks in advance.

Question by:tigriswoods
  • 4
  • 2
  • 2
LVL 25

Expert Comment

ID: 20335880
you need something like

where (@filterableColumnFilter is null) or (filterableColumn = @filterableColumnFilter)
    and (@filterableColumnFilter2 is null) or (filterableColumn = @filterableColumnFilter2)
LVL 25

Accepted Solution

imitchie earned 500 total points
ID: 20335887
if you had a table, say Customer with Code and Name, and you want them to be filterable, but allow for not filtering, then

create proc getCustomers( @code varchar(10), @name varchar(50) )
select Code, Name from Customer
where (@Code is null) or (Code = @Code)
    and (@Name is null) or (Name = @Name)

Author Comment

ID: 20336278
Hard to believe it's that simple but my initial testing is looking positive.  I'll test it more thoroughly and get back to you.  THANKS !
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

LVL 23

Expert Comment

ID: 20336559
<<I really need expert advice on the best approach to how to make a performant, parameterized query that accepts optional parameters on columns that may be NULLABLE. >>
In short, there are satisfactory solution with evaluating NULLS.  The best way to deal with NULLS is to not use them at all...For optional attributes, create an additional table and establish a 1:0 relationship with the mandatory table based on the base table.

Ex: suppose you have an *employee* (emp#, fname, lname, fixed_phone) table that may or may not have a cell phone number.  The correct solution to the problem is to create an *employee_cellphone* table with(emp#, cellphone).  That way, once you want you just do an inner join it will be much easier to handle....

Hope this helps...

Hope this helps...

Author Comment

ID: 20336643
Yo habla un poquito SQL solamente (I speak only a litle SQL...)
I am presenting data from many tables in a gridview based on the search criteria entered by  the customer. One of the NULLABLE fields is the result of a LEFT OUTER JOIN of one table (Results)  with another table (TestOrders).  The TestOrders exist, but the Results for the Order may not yet exist. I need to ensure I do not exclude any TestOrders which have no Results -- unless I'm using the Results_received_date as part of the criteria.  In that case, only TestOrders which have Results will be displayed in the gridview. The prioblem I was having (and which appears to have been solved by the suggestion from imitchie) was that this statement in my sproc would exclude TestOrders for which Results did not yet exist whenever I queried on other columns:

AND (@Results_received_date >= ISNULL(@Result_received_date, Result_received_date))

I still have lots to learn -- I was also wondering about using a sproc vs creating a Dynamic SQL and executing it via EXEC.  Now that it appears that the sproc will work after all, I'm hoping I'm heading in a better, more performant direction than creating on-the-fly queries in my code. :)

LVL 23

Expert Comment

ID: 20340693
<<I was also wondering about using a sproc vs creating a Dynamic SQL>>
nothing prevents you from using dynamic SQL inside a stored proc...

Author Comment

ID: 20345894
At this stage of the game, the suggestion by imitchie has resolved the problem I was having.  Thank you!! I have tested this thoroughly and it is working just fine.  Whether or not this is the most performant query, I cannot say, but at least I now have a parameterized query using NULLABLE columns.

Author Closing Comment

ID: 31410590
Thanks again!

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
SQL Server / Update DB? 22 38
SQL, add where clause 5 24
fault SQL backup files that wont restore - how common 3 29
Evaluate Twice? 2 11
Introduction In my previous article ( I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
This article shows gives you an overview on SQL Server 2016 row level security. You will also get to know the usages of row-level-security and how it works
Using examples as well as descriptions, and references to Books Online, show the documentation available for date manipulation functions and by using a select few of these functions, show how date based data can be manipulated with these functions.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question