quinta-feira, 22 de outubro de 2009

Valores nulos em chave única no SQL Server

O Microsoft SQL Server tem uma característica que eu não gosto nem um pouco: em uma chave única dois valores nulos são considerados iguais.

Imagine uma tabela com os campos abaixo, tendo uma chave única com o campo CPF.
ID Nome CPF
1 João 123.456.789-00
2 Pedro NULL
3 Bino NULL

No SQL Server, ao contrário de outros bancos como o PostgreSQL, esses dados não seriam válidos. Ao tentar inserir o terceiro registro seria gerado um erro de chave duplicada.

Para contornar esse problema existe um truque denominado Nullbuster. Descobri essa técnica por acaso ao ler um post do Karl Seguin. Pesquisando na internet descobri que os créditos são dados ao Steve Kass, porém não encontrei nenhum link onde pudesse confirmar isso.

O truque é bastante simples, veja o SQL abaixo:
CREATE TABLE dupNulls (
  pk int identity(1,1) primary key,
  X  int NULL,
  nullbuster as (case when X is null then pk else 0 end),
  CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster)
)
Repare que foi criado um campo adicional denominado “nullbuster” onde o valor será igual a PK se o valor for NULO ou 0 se o valor estiver preenchido. A chave única então é composta dos dois campos.

A tabela exibida acima ficaria com os valores:
ID Nome CPF Nullbuster
1 João 123.456.789-00 0
2 Pedro NULL 2
3 Bino NULL 3

Um truque bastante simples que resolve alguns problemas.