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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 !
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Everyone has problem when going to load data into Data warehouse (EDW). They all need to confirm that data quality is good but they don't no how to proceed. Microsoft has provided new task within SSIS 2008 called "Data Profiler Task". It solve th…
I have a large data set and a SSIS package. How can I load this file in multi threading?
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

752 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