Using nullable columns in a WHERE clause
-
13-09-2019 - |
Question
Assume a table definition in SQL Server as follows:
CREATE TABLE MyTable (
Id UNIQUEIDENTIFIER NULL,
Info VARCHAR(MAX)
)
And a query:
DECLARE @id UNIQUEIDENTIFIER
DECLARE @info VARCHAR(MAX)
IF @id IS NOT NULL
BEGIN
SELECT @info = Info
FROM MyTable
WHERE Id = @id
END
In that case, the Visual Studio static code analyzer produces the following error:
Warning : SR0007 : Microsoft.Performance : Nullable columns can cause final results to be evaluated as NULL for the predicate.
I don't see the problem here. The error is related to performance; MSDN says I should use ISNULL() -- but an equals comparison against NULL is always false, right? Am I missing something, or is the warning just wrong?
Solution
I think it's referring to the WHERE clause. It's saying that both your parameter and your column can be NULL, in which case your WHERE clause no longer evaluates to true/false. By funneling your nullable column into one that always has a value defined (via ISNULL), you're in better shape, logic-wise.
Here's the Microsoft documentation on that error.
On the aside, NULLs supposedly make queries a skosh slower.
OTHER TIPS
I think the analyzer might just not be taking into account your IF statement.
Your code seems correct to me.
I think it's a spurious warning - can you suppress it on a case-by-case basis, or that particular warning completely?
What happens when you do this?:
CREATE TABLE MyTable (
Id UNIQUEIDENTIFIER NOT NULL,
Info VARCHAR(MAX)
)
Null comparison depends on setup.
When SET ANSI_NULLS is ON, all comparisons against a null value evaluate to UNKNOWN
When SET ANSI_NULLS is ON, a SELECT statement that uses WHERE column_name = NULL
returns zero rows even if there are null values in column_name.
A SELECT statement that uses WHERE column_name <> NULL returns zero rows even if there are no nnull values in column_name.
When SET ANSI_NULLS is OFF, the Equals (=) and Not Equal To (<>) comparison operators do not follow the ISO standard.
This is from here.
IF @id IS NOT NULL
should be replaced with
IF ISNull(@id, -1) <> -1
@ Raj: "IF ISNull(@id, -1) <> -1"
I would not do it as it actually replaces the table entry