Mam tabeli SQL zdefiniowane jak poniżej:kompozytowe klucze podstawowe i Klucz obcy błąd ograniczenie
CREATE TABLE [TestComposite] (
ID int,
SiteUrl nvarchar(255),
Name nvarchar(max) NOT NULL,
ParentID int NULL,
PRIMARY KEY (ID, SiteUrl)
);
przedmioty i foldery są przechowywane wewnątrz tej samej tabeli, jeśli element jest wewnątrz folderu, kolumna ParentID jest ID folderu. Chciałbym móc usuwać elementy/foldery CASCADE po usunięciu folderu.
Przykładem może być bardziej wyraźne:
INSERT INTO [TestComposite] VALUES (1, 'site1', 'Item1', NULL)
INSERT INTO [TestComposite] VALUES (2, 'site1', 'Item2', NULL)
INSERT INTO [TestComposite] VALUES (3, 'site1', 'Folder1', NULL)
INSERT INTO [TestComposite] VALUES (4, 'site1', 'Folder1.Item1', 3)
INSERT INTO [TestComposite] VALUES (5, 'site1', 'Folder1.Item2', 3)
INSERT INTO [TestComposite] VALUES (6, 'site1', 'Folder1.Folder1', 3)
INSERT INTO [TestComposite] VALUES (7, 'site1', 'Folder1.Folder1.Item1', 6)
etc...
Więc jeśli usunę element 3 (folder), chcę przedmioty/foldery 4, 5, 6 i 7, które mają zostać usunięte zbyt.
Próbowałem dodać ograniczenie podobny do:
ALTER TABLE [TestComposite]
ADD CONSTRAINT fk_parentid
FOREIGN KEY (ParentID, SiteUrl)
REFERENCES [TestComposite] (ID, SiteUrl) ON DELETE CASCADE;
Ale to daje mi ten błąd:
Wprowadzenie ograniczenia klucz obcy „fk_parentid” na stole „TestComposite” może powodować cykli lub wiele ścieżek kaskadowe. Określ ON DELETE NO ACTION lub ON UPDATE NO ACTION lub zmodyfikuj inne ograniczenia klucza OBCEGO.
Próbowałem również dodać drugą kolumnę SiteUrl o nazwie ParentSiteUrl, na wypadek gdyby problem polegał na tym, że kolumna nie może być częścią tego samego FK/PK, ale mam ten sam komunikat o błędzie.
Czy robię coś nie tak?
Dziękuję
Mogę się mylić, ponieważ jeszcze tego nie przetestowałem, ale nie sądzę, żeby w moim przypadku usunięto element 7, ponieważ znajduje się on na innym poziomie hierarchii?! –
'@ OmaR': tak, usunie także' 7'. To rekurencyjny "CTE". – Quassnoi
Dziękuję, działa świetnie. Nie wiedziałem o rekurencyjnym CTE. Wygląda na to, że działa zarówno na SQL Server 2005, jak i na SQL Server 2008. –