Visual Basic, VB .NET, ASP, Active X, Access, SQL Server

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.