首页 > 解决方案 > SQL Server 引入 FOREIGN KEY 约束可能导致循环或多个级联路径

问题描述

我有两张桌子:T_User and T_Order

T_User
--------
ID
Name

T_Order必须要外键T_User

T_Order
--------
ID
FK_UserActionOwnerID
FK_UserActionReceiverID

然后我在我的图表上建立了两个关系,从T_User ID两个 FK 到T_Order. 我还将这两种关系设置为delete and update rulescascade因为我想如果T_User记录将被删除,因此记录T_Order应该被删除,或者如果T_User ID会改变然后也更新它T_Order.但是我得到以下错误:

'T_User' 表已成功保存 'T_Order' 表 - 无法创建关系 'FK_T_Order_T_Users1'。在表“T_Order”上引入 FOREIGN KEY 约束“FK_T_Order_T_Users1”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束或索引。请参阅以前的错误。

实物图: 点这里

标签: sql-server

解决方案


键约束可能导致循环或多个级联路径?@Martin-Brown 链接的问题建议使用触发器而不是级联外键。这是一个使用INSTEAD OF DELETE触发器来做(我认为)你想做的事情的例子。

-- Create tables
create table dbo.T_User (
    ID int identity not null primary key,
    Name varchar(100) not null
)

create table dbo.T_Order (
    ID int identity not null primary key,
    FK_UserActionOwnerID int not null,
    FK_UserActionReceiverID int not null
)
go

-- Create foreign keys
alter table dbo.T_Order add constraint FK_T_Order_T_Users1 FOREIGN KEY (FK_UserActionOwnerID) REFERENCES dbo.T_User (ID) 
alter table dbo.T_Order add constraint FK_T_Order_T_Users2 FOREIGN KEY (FK_UserActionReceiverID) REFERENCES dbo.T_User (ID) 
go

-- Create trigger
create trigger tr_T_User_Delete on dbo.T_User instead of delete as
begin

    if (@@rowcount = 0) return

    delete o from dbo.T_Order o inner join deleted d on d.ID = o.FK_UserActionOwnerID

    delete o from dbo.T_Order o inner join deleted d on d.ID = o.FK_UserActionReceiverID

    delete u from dbo.T_User u inner join deleted d on d.ID = u.ID  

end
go

-- Demo
insert dbo.T_User (Name) values ('Peter'), ('Paul') -- Assume identity ID 1 and 2

insert dbo.T_Order (FK_UserActionOwnerID, FK_UserActionReceiverID) values (1, 1), (1, 2), (2, 2)

select * from dbo.T_Order

delete from dbo.T_User where ID = 1

select * from dbo.T_Order

您可以INSTEAD OF UPDATE以相同的方式使用触发器,但您可能想考虑更新 ID 是否有意义 - 我通常不会想到这一点。


推荐阅读