复合主键和外键约束错误

时间:2010-03-03 12:57:43

标签: sql sql-server foreign-keys constraints composite

我有一个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;

但它给了我这个错误:
在表'TestComposite'上引入FOREIGN KEY约束'fk_parentid'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

我还尝试添加名为ParentSiteUrl的第二个SiteUrl列,以防问题是列不属于同一个FK / PK,但我有相同的错误消息。

我做错了吗?

谢谢,

4 个答案:

答案 0 :(得分:6)

创建ON DELETE NO ACTION约束并使用此约束删除所有记录及其子项:

WITH    q AS
        (
        SELECT  id, SiteURL
        FROM    TestComposite
        WHERE   id = 3
                AND SiteURL = 'site1'
        UNION ALL
        SELECT  tc.id, tc.SiteURL
        FROM    q
        JOIN    TestComposite tc
        ON      tc.ParentID = q.Id
                AND tc.SiteURL = q.SiteURL
        )
DELETE
FROM    TestComposite
WHERE   EXISTS
        (
        SELECT  id, SiteURL
        INTERSECT
        SELECT  *
        FROM    q
        )

答案 1 :(得分:1)

如果您有SQL Server 2008,请使用HierarchyID类型进行此项工作。

答案 2 :(得分:0)

我认为你想要做的事情可以通过添加一个名为ParentId的新列来实现,然后将其声明为具有主键的外键。 这样问题就会解决,你仍然可以做你想做的一切

答案 3 :(得分:0)

问题是你创建了递归级联的可能性 - 当每个被级联删除时都可以创建任意数量的后续删除。 MS SQL不支持它。尝试手动删除代码中的它们。顺便说一句,我不建议级联删除。

http://support.microsoft.com/kb/321843