Supongamos que tenemos una tabla que tiene una restricción de clave externa para sí misma, como tal:
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 tabla tendrá los siguientes registros:
FooId ParentFooId
----- -----------
1 3
2 1
3 2
Hay casos en los que este tipo de diseño podría tener sentido (por ejemplo, la típica relación "empleado-y-jefe-empleado"), y en cualquier caso: estoy en una situación en la que tengo esto en mi esquema.
Desafortunadamente, este tipo de diseño permite circularidad en los registros de datos, como se muestra en el ejemplo anterior.
Mi pregunta entonces es:
- ¿Es posible escribir una restricción que verifique esto? y
- ¿Es factible escribir una restricción que verifique esto? (si es necesario solo hasta una cierta profundidad)
Para la parte (2) de esta pregunta, puede ser relevante mencionar que espero solo cientos o quizás en algunos casos miles de registros en mi tabla, normalmente no anidados a más de 5 a 10 niveles.
PD. MS SQL Server 2008
Actualización 14 de marzo de 2012
Hubo varias buenas respuestas. Ahora he aceptado el que me ayudó a comprender la posibilidad / factibilidad mencionada. Sin embargo, hay varias otras respuestas excelentes, algunas con sugerencias de implementación, por lo que si aterrizó aquí con la misma pregunta, eche un vistazo a todas las respuestas;)