SQL: Valores NULL na cláusula WHERE
Esta dica trata de valores Null em cláusulas WHERE sob o SQL Server e também de uma pequena diferença entre o Access 97 e o Access 2000 no tocante a estes valores.
Uma consulta do tipo SELECT retorna todas as linhas para as quais a cláusula WHERE retorna True. Contudo, muitos desenvolvedores se confundem assumindo que a consulta retornará todos os registros para os quais a cláusula WHERE retorne qualquer valor diferente de False. Isto é uma causa comum de bugs.
Para explicar a razão, considere que a linguagem SQL usa uma lógica de três valores: True, False e Null. Qualquer valor Null em uma expressão torna toda a expressão Null (com algumas exceções citadas abaixo). Por exemplo, o seu senso comum sugere que o SELECT abaixo retorna todas as linhas em uma tabela:
SELECT * FROM Orders
WHERE (total < 1000 Or total >= 1000)
O que acontece, contudo, é que o SELECT não incluirá os registros para os quais o campo Total é Null, porque este valor faz com que toda a expressão contida na cláusula WHERE seja avaliada como Null. Eis aqui um outro exemplo:
SELECT * FROM Pedidos WHERE Total = 0
A consulta acima retorna todos os pedidos para os quais Total é zero, mas não aqueles para os quais o Total é Null. Se você quer incluir estes últimos, precisa pesquisar explicitamente pelos valores Null:
SELECT * FROM Pedidos
WHERE total = 0 OR total IS NULL
ISNULL é uma função T-SQL que é constantemente usada para lidar com valores Null. Simplesmente, ela sempre retorna o seu primeiro argumento exceto quando ele é Null (neste caso ela retorna o segundo argumento). Veja como você pode reescrever a consulta acima para lidar com valores Null:
-- converte valores Null
para zero antes de compará-los
SELECT * FROM Pedidos WHERE ISNULL(total, 0) = 0
Além disto, a T-SQL estende o padrão ANSI 92 e suporta Null também em cláusulas IN, de modo que você pode reescrever a consulta acima como abaixo:
SELECT * FROM Pedidos WHERE total IN (0, NULL)
Como observação final,
quando se usa Access 97 é possível usar a sintaxe = Null, mas esta sintaxe
não funciona no Access 2000, onde você deve usar acertadamente Is Null.