SQL Server 2008 - 多个级联FK - 我需要一个触发器吗?

RPM*_*984 5 sql-server foreign-keys sql-server-2008 relationships cascading-deletes

我之间有1 ..*关系的用户帖子.(一个用户有很多帖子)

Post有一个名为"UserId"的FK,它映射到User表上的"UserId"字段.

我试图将此FK设置为​​Cascade UPDATE/DELETE,但是我收到此错误:

'用户'表成功保存'帖子'表 - 无法创建关系'FK_Posts_Users'.
在表'Posts'上引入FOREIGN KEY约束'FK_Posts_Users'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.无法创建约束.查看以前的错误.

我有一个名为PostHelpful的表.One Post有很多帮助.

有用的是级联FK到用户(所以当用户被删除时,他们的帮助也被删除).

但我认为这是"多重级联路径"投诉的原因.

因为如果我删除用户(当前),它将删除他们的帮助.但我试图添加一个cacade也发布,它会删除帖子,然后尝试删除该帖子的有用的(有帮助也有一个级联FK发布).在那种情况下,SQL选择哪个级联FK?

以下是有问题的三个表的数据库图:

在此输入图像描述

正如你所看到的,"PostHelpful"对于"Post"和"User"都是一个孩子(两者都有FK).

所以我不能让两个键级联?我是否需要在"用户"(AFTER DELETE)上触发以手动删除有用的(以及引用用户的其他表).

Phi*_*mer 3

SQL Server 选择哪条路径并不重要,它不允许这样做,这样它就不会陷入妥协的境地。当我们遇到这种情况时,我们不得不求助于触发器。

1)如错误消息所述,将Users_PostHelpfuls FK 更改为ON DELETE NO ACTION

2)向用户添加INSTEAD OF DELETE触发器:

CREATE TRIGGER dbo.Users_IO_Delete 
ON dbo.Users
INSTEAD OF DELETE
AS
BEGIN;
    DELETE FROM dbo.PostHelpfuls WHERE UserId IN (SELECT UserId FROM deleted);

    DELETE FROM dbo.Users WHERE UserId IN (SELECT UserId FROM deleted);
END;
Run Code Online (Sandbox Code Playgroud)

现在,FK 仍将强制执行 DRI,但触发器是级联删除而不是 FK 约束。

您可以将上述步骤中的PostHelpfuls替换为Posts 。但执行此操作时,最好使用触发器来删除独立程度较低的实体的记录。换句话说,Posts更有可能与UsersPostHelpfuls旁边的表相关,而不是PostHelpfuls与UsersPosts旁边的表相关。