2在2个表之间的Sql Server中级联删除

时间:2013-09-27 13:45:12

标签: sql-server sql-server-2008 foreign-key-relationship

假设我有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.

有没有办法在不使用触发器的情况下执行此操作,或者触发器是执行此操作的最佳方法

2 个答案:

答案 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

就像我说的,我怀疑这是一种正确的做法