У меня есть таблица SQL, определенная как показано ниже:Композитных первичные ключи и внешние ключи Ошибка ограничения
CREATE TABLE [TestComposite] (
ID int,
SiteUrl nvarchar(255),
Name nvarchar(max) NOT NULL,
ParentID int NULL,
PRIMARY KEY (ID, SiteUrl)
);
товаров и папки, которые хранятся в той же таблицу, если элемент находится внутри папки, столбец ParentID является ID папки. И я хотел бы иметь возможность удалять элементы/папки CASCADE при удалении папки.
Примером может быть более явным:
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...
Так, если удалить пункт 3 (папка), я хочу те элементы/папки 4, 5, 6 и 7, которые будут удалены тоже.
Я пытался добавить ограничение, похожее на:
ALTER TABLE [TestComposite]
ADD CONSTRAINT fk_parentid
FOREIGN KEY (ParentID, SiteUrl)
REFERENCES [TestComposite] (ID, SiteUrl) ON DELETE CASCADE;
Но это дает мне эту ошибку:
Вводя ограничение FOREIGN KEY «fk_parentid» на столе «TestComposite» может вызвать циклы или несколько путей порогов. Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION или измените другие ограничения FOREIGN KEY.
Я также попытался добавить второй столбец SiteUrl с именем ParentSiteUrl, в случае, если проблема заключалась в том, что столбец не является частью одного и того же FK/PK, но у меня такое же сообщение об ошибке.
Я делаю что-то неправильно?
Спасибо,
Возможно, я ошибаюсь, поскольку я еще не тестировал его, но я не думаю, что он удалит элемент 7 в моем случае, так как он находится на другом уровне иерархии?! –
'@ OmaR': да, он также удалит' 7'. Это рекурсивный «CTE». – Quassnoi
Спасибо, он отлично работает. Я не знал о рекурсивном CTE. И похоже, что он работает как на SQL Server 2005, так и на SQL Server 2008. –