如何删除记录,子记录和孙子记录?

时间:2016-01-18 21:53:56

标签: sql sql-server inner-join

我有三个表 - 乐队,演出和分配(为进入它的注册用户分配一个演出,以便在演出和用户之间创建许多关系。)

表格是:

Bands: bandID, bandname
Gigs: GigID, bandID, venue, date
Assigns: assignID, gigid, userid (which is then linked to the users table)

网站上的一个功能就是删除一个乐队,然后它会去#34;哦,在删除乐队之前,它会删除所有这些演出",然后用户选择确认,所以上。

我需要一个删除波段的查询,然后删除gigs.bandID = bands.bandID的gigs,然后删除assigns.gigID = gigs.gigID的分配。

我已经解决了SELECT语句,它通过向bandid提供我想要从assigns表中删除的记录。

SELECT assigns.*
FROM   bands INNER JOIN
   gigs ON bands.bandid = gigs.bandid INNER JOIN
   gigsaccass ON gigs.gigid = gigsaccass.gigid AND bands.bandid = 91

但是如何从中创建DELETE语句?

4 个答案:

答案 0 :(得分:2)

有两种方法可以做到这一点,其中一种方法是Cascading Delete。另一种方法是使用多个查询有效地重新创建级联删除。我个人更喜欢第二种选择,因为它可以让你更多地控制你的数据。如果您不是非常小心,利用级联删除(特别是在生产环境中)可能会导致相当严重的后果。撤消单个记录删除可能相当容易(如果它是一个简单的表),如果没有数据库备份,撤消无意中击中20个不同表的级联删除几乎是不可能的。

答案 1 :(得分:2)

有很多方法可以解决这个问题,但如果您不想做ON DELETE CASCADE约束选项,这就是我要去的路线......

Declare @bandID Int
Set     @bandID = 91

--      Delete the associated gigsaccess records
DELETE  ga
FROM    bands As b
INNER   JOIN gigs As g  
        ON  b.bandid = g.bandid 
INNER   JOIN gigsaccass As ga 
        ON  g.gigid = ga.gigid 
WHERE   b.bandid = @bandID

--      Delete the associated gigs records
DELETE  g
FROM    bands As b
INNER   JOIN gigs As g  
        ON  b.bandid = g.bandid 
WHERE   b.bandid = @bandID

--      Delete the band record
DELETE  b
FROM    bands As b
WHERE   b.bandid = @bandID

答案 2 :(得分:0)

正如jae555所说,我会说ON DELETE CASCADE触发器是可行的方法。

答案 3 :(得分:0)

级联删除很简单..你只需要以某种方式创建外键。

-- foreign key constraint
ALTER TABLE [dbo].[Gigs]  WITH CHECK 
ADD CONSTRAINT [FK_Gigs_Band] FOREIGN KEY([BandID])
REFERENCES [dbo].[Bands] ([BandID])
ON DELETE CASCADE
GO

-- foreign key constraint
ALTER TABLE [dbo].[Assigns]  WITH CHECK 
ADD CONSTRAINT [FK_Assigns_Gigs] FOREIGN KEY([GigID])
REFERENCES [dbo].[Gigs] ([GigID])
ON DELETE CASCADE
GO

如果你有一个外键,请确保先删除当前的外键..

另一种方式是创建触发器..特别是Instead of Delete触发器

CREATE TRIGGER [DELETE_Bands]
   ON dbo.[Bands]
   INSTEAD OF DELETE
AS 
BEGIN
 SET NOCOUNT ON;
 DELETE FROM [Gigs] WHERE BandID IN (SELECT BandID FROM DELETED)
 DELETE FROM [Bands] WHERE BandID IN (SELECT BandID FROM DELETED)
END
GO

CREATE TRIGGER [DELETE_Gigs]
   ON dbo.[Gigs]
   INSTEAD OF DELETE
AS 
BEGIN
 SET NOCOUNT ON;
 DELETE FROM [Assigns] WHERE GigID IN (SELECT GigID FROM DELETED)
 DELETE FROM [Gigs] WHERE GigID IN (SELECT GigID FROM DELETED)
END
GO