In SQL server if you have nullParam=NULL
in a where clause, it always evaluates to false. This is counterintuitive and has caused me many errors. I do understa
The concept of NULL is questionable, to say the least. Codd introduced the relational model and the concept of NULL in context (and went on to propose more than one kind of NULL!) However, relational theory has evolved since Codd's original writings: some of his proposals have since been dropped (e.g. primary key) and others never caught on (e.g. theta operators). In modern relational theory (truly relational theory, I should stress) NULL simply does not exist. See The Third Manifesto. http://www.thethirdmanifesto.com/
The SQL language suffers the problem of backwards compatibility. NULL found its way into SQL and we are stuck with it. Arguably, the implementation of NULL
in SQL is flawed (SQL Server's implementation makes things even more complicated due to its ANSI_NULLS
option).
I recommend avoiding the use of NULLable columns in base tables.
Although perhaps I shouldn't be tempted, I just wanted to assert a corrections of my own about how NULL
works in SQL:
NULL
= NULL
evaluates to UNKNOWN
.
UNKNOWN
is a logical value.
NULL
is a data value.
This is easy to prove e.g.
SELECT NULL = NULL
correctly generates an error in SQL Server. If the result was a data value then we would expect to see NULL
, as some answers here (wrongly) suggest we would.
The logical value UNKNOWN
is treated differently in SQL DML and SQL DDL respectively.
In SQL DML, UNKNOWN
causes rows to be removed from the resultset.
For example:
CREATE TABLE MyTable
(
key_col INTEGER NOT NULL UNIQUE,
data_col INTEGER
CHECK (data_col = 55)
);
INSERT INTO MyTable (key_col, data_col)
VALUES (1, NULL);
The INSERT
succeeds for this row, even though the CHECK
condition resolves to NULL = NULL
. This is due defined in the SQL-92 ("ANSI") Standard:
11.6 table constraint definition
3)
If the table constraint is a check constraint definition, then let SC be the search condition immediately contained in the check constraint definition and let T be the table name included in the corresponding table constraint descriptor; the table constraint is not satisfied if and only if
EXISTS ( SELECT * FROM T WHERE NOT ( SC ) )
is true.
Read that again carefully, following the logic.
In plain English, our new row above is given the 'benefit of the doubt' about being UNKNOWN
and allowed to pass.
In SQL DML, the rule for the WHERE
clause is much easier to follow:
The search condition is applied to each row of T. The result of the where clause is a table of those rows of T for which the result of the search condition is true.
In plain English, rows that evaluate to UNKNOWN
are removed from the resultset.