Suponha que tenhamos uma tabela que tenha uma restrição de chave estrangeira, assim:
CREATE TABLE Foo
(FooId BIGINT PRIMARY KEY,
ParentFooId BIGINT,
FOREIGN KEY([ParentFooId]) REFERENCES Foo ([FooId]) )
INSERT INTO Foo (FooId, ParentFooId)
VALUES (1, NULL), (2, 1), (3, 2)
UPDATE Foo SET ParentFooId = 3 WHERE FooId = 1
Esta tabela terá os seguintes registros:
FooId ParentFooId
----- -----------
1 3
2 1
3 2
Há casos em que esse tipo de design pode fazer sentido (por exemplo, o relacionamento típico de "funcionário e chefe-funcionário") e, em qualquer caso: estou em uma situação em que tenho isso no meu esquema.
Infelizmente, esse tipo de design permite circularidade nos registros de dados, como mostra o exemplo acima.
Minha pergunta então é:
- É possível escrever uma restrição que verifique isso? e
- É possível escrever uma restrição que verifique isso? (se necessário apenas até uma certa profundidade)
Para a parte (2) desta pergunta, pode ser relevante mencionar que espero apenas centenas ou talvez, em alguns casos, milhares de registros em minha tabela, normalmente não aninhados mais do que cerca de 5 a 10 níveis.
PS. MS SQL Server 2008
Atualização 14 de março de 2012
Houve várias boas respostas. Aceitei agora o que me ajudou a entender a possibilidade / viabilidade mencionada. Existem várias outras ótimas respostas, algumas com sugestões de implementação também; portanto, se você chegou aqui com a mesma pergunta, consulte todas as respostas;)