假设我有2张桌子
CREATE TABLE [dbo].[People](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Nom] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
和
CREATE TABLE [dbo].[Transactions](
[ID] [int] IDENTITY(1,1) NOT NULL,
[BUYER_ID] [int] NOT NULL,
[SELLER_ID] [int] NOT NULL,
[DateTransaction] [datetime] NOT NULL,
CONSTRAINT [PK_Transactions] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
逻辑是交易表需要来自人员表,买方和卖方的2条记录。
我要做的是在BUYER_ID和SELLER_ID列上实现级联删除。
但是,我可以毫不费力地添加一个(或者),但如果我尝试添加第二个,当我去保存时,我收到错误消息...
Unable to create relationship 'FK_Transactions_Buyer'.
Introducing FOREIGN KEY constraint 'FK_Transactions_Buyer' on table 'Transactions' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
有没有办法在不使用触发器的情况下执行此操作,或者触发器是执行此操作的最佳方法
答案 0 :(得分:1)
引用事务的人的FK约束可能导致此问题。 如果不是这种情况,我认为答案是将两个键都包含在一个约束中。 如果买方和卖方ID都相同,并且该人被删除,则两个约束可能会寻求删除同一行。 这是我能想到的唯一场景,SQL服务器可能会试图避免...
道歉我无法更明确!
答案 1 :(得分:0)
这就是我最终做到的方式,我非常怀疑这是最好的方法。
我将外键修改为不强制外键约束。
ALTER TABLE [dbo].[Transactions] NOCHECK CONSTRAINT [FK_Transactions_Buyer]
和
ALTER TABLE [dbo].[Transactions] NOCHECK CONSTRAINT [FK_Transactions_Seller]
并修改了事务表以添加IsDeleted字段
[IsDeleted] [bit] NULL
最后,我在People表中添加了一个Delete触发器,只要在People Table中删除了Buyer_ID或Seller_Id,就会在事务表中将IsDeleted设置为TRUE
最后在触发器结束时,我删除了事务中所有将IsDeleted标志设置为true的记录。
CREATE TRIGGER [dbo].[deletePeople]
ON [dbo].[People]
AFTER DELETE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @DeletedId INT
SELECT @DeletedId = id FROM deleted
-- Insert statements for trigger here
Update dbo.Transactions SET IsDeleted = 1 WHERE BUYER_ID = @deletedId or SELLER_ID = @deletedId
DELETE FROM dbo.Transactions WHERE IsDeleted = 1
END
就像我说的,我怀疑这是一种正确的做法