Searchable Nullable Optional Fields in SQL
Here's just a quick tip I came across (this is actually a good read on Whidbey Data Beta 2 features), which is pretty handy (and not so obvious) even if that's not what the article is really about. If you have a field in a table that you need to search on, but the field allows nulls AND you want to be able to ignore the field completely, then check out this example:
CREATE PROCEDURE dbo.FindCustomers
(
@FirstName varchar(50),
@LastName varchar(50),
@Email varchar(100),
@Age tinyint
)
AS
SELECT
CustomerID,
FirstName,
LastName,
Email,
Age
FROM
Customers
WHERE
FirstName = ISNULL(@FirstName, FirstName) AND
LastName = ISNULL(@LastName, LastName) AND
Email = ISNULL(@Email, Email) AND
Age = ISNULL(@Age, Age)
ORDER BY
LastName,
FirstName
Here, if we pass in an Age of 25, we get back all the Customers that are 25 years old. However, if we pass in NULL, signifying that we don't want to search on that field at all, only the rows that do not have a NULL value for Age get returned, which is not what we want. We want ALL rows to be returned regardless of Age. Highlighted in bold is the change you'd need to fix it to work the way you want it to:
CREATE PROCEDURE dbo.FindCustomers
(
@FirstName varchar(50),
@LastName varchar(50),
@Email varchar(100),
@Age tinyint
)
AS
SELECT
CustomerID,
FirstName,
LastName,
Email,
Age
FROM
Customers
WHERE
FirstName = ISNULL(@FirstName, FirstName) AND
LastName = ISNULL(@LastName, LastName) AND
Email = ISNULL(@Email, Email) AND
(Age = ISNULL(@Age, Age) OR (Age IS NULL AND @Age IS NULL))
ORDER BY
LastName,
FirstName
The problem (you probably already noticed) was that NULL can not be compared using the equal operator, only with the IS operator. Age = NULL will always return False. The above bolded changes takes care of this problem. This is one of those simple things I just never thought of until I came across it in the above article...silly me...I'll never forget it now. Hope this helps a few folks as well! :)
UPDATE: Read the comments below for more...