两个外键引用一个表 - ON UPDATE SET NULL不起作用

Woj*_*lik 7 t-sql sql-server cascade constraints foreign-keys

我在表中有两个外键.我们假设该表被调用News并具有外键,updatedById并且createdById两者都指向userId表中Users.

现在我想在NULL删除用户时设置外键,但是当我尝试设置ON DELETE SET NULL该关系时,我得到:

在表'新闻'上引入FOREIGN KEY约束'FK_News_Users'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.

我不明白为什么两个外键都不能设置为null?

pet*_*erm 8

多个级联操作

由单个DELETE或UPDATE触发的一系列级联引用操作必须形成不包含循环引用的树.在DELETE或UPDATE导致的所有级联参照操作的列表中,任何表都不会出现多次.此外,级联引用操作树不得包含任何指定表的多个路径.树的任何分支在遇到已指定NO ACTION的表或默认值时结束.

可能在这种情况下,您可能需要考虑实现逻辑删除用户而不是物理删除用户的功能(例如,通过在Users表中引入标记字段Active或Deleted ).这样,所有关系都保持不变,可以追溯分析.

但是如果你仍然需要ON DELETE SET NULL为两个FK 实现,你可以像这样FOR DELETEUser表上使用触发器:

CREATE TRIGGER Users_News_Delete_Trigger 
ON Users FOR DELETE
AS BEGIN
    UPDATE News SET createdById = NULL 
     WHERE createdById = DELETED.id;
    UPDATE News SET updatedById = NULL 
     WHERE updatedById = DELETED.id;
END
Run Code Online (Sandbox Code Playgroud)

  • 在delete set null null上声明的外键中,删除信息的确是*数据库设计者认为合适的操作.这就是为什么两个`on delete set null`和`on delete cascade`都存在 - 删除信息 - 以及为什么它们自1992年以来一直是SQL标准的一部分.(那些不是OP的真实表格.不是关于`on delete set null`是否合适.问题是它在SQL Server中在这些情况下失败的原因.) (3认同)
  • @WojciechKulik:严格来说,这是一个实施质量问题.其他平台正确处理您的场景,将两个引用值都设置为NULL.例如,PostgreSQL. (2认同)
  • SQL服务器的开发人员是业务中最懒的,还是最无能的,他们无法弄清楚如何实现这一点?也许两者? (2认同)