/*
Autor : Fausto Odilon
Data : 03/04/2009
Descrição:
Este Script demonstra uma falha de validação de Foreign Keys do SQL Server.
Quando uma Foreign Key é composta por mais de um campo com preenchimento opcional (NULL),
se um dos campos for informado como nulo, os demais não serão validados, permitindo
qualquer valor, ou seja, a inclusão de lixos na tabela relacionada.
*/

create table TMP_Teste_PK
(
Campo1 int NOT NULL,
Campo2 int NOT NULL,
Campo3 int NOT NULL,
CONSTRAINT PK_TMP_Teste_PK
PRIMARY KEY CLUSTERED (Campo1, Campo2, Campo3)
)

insert into TMP_Teste_PK
select 1, 1, 1
union select 1, 2, 1
union select 1, 3, 1
union select 2, 1, 2
union select 2, 2, 2
union select 3, 1, 2
union select 3, 2, 2

create table TMP_Teste_FK
(
Campo1 int NULL,
Campo2 int NULL,
Campo3 int NULL,
CONSTRAINT PK_TMP_Teste_FK
foreign KEY (Campo1, Campo2, Campo3)
references TMP_Teste_PK (Campo1, Campo2, Campo3)
)

truncate table TMP_Teste_FK
insert into TMP_Teste_FK
select 1, 1, 1 — Dados OK
union select 1, 2, 1 — Dados OK
union select 2, 2, 2 — Dados OK
union select 2, NULL, 1 — Dados Inválidos
union select 5, NULL, 2 — Dados Inválidos
union select -99, NULL, 3 — Dados Inválidos
union select NULL, 98, -17 — Dados Inválidos

select * from TMP_Teste_FK

drop table TMP_Teste_FK
drop table TMP_Teste_PK