Reputation:
I have three tables - bands, gigs and assigns (which assigns a gig to the registered user that entered it to create a many-many relationship between gigs and users.)
The tables are:
Bands: bandID, bandname
Gigs: GigID, bandID, venue, date
Assigns: assignID, gigid, userid (which is then linked to the users table)
A function on the site is to delete a band, but then it goes "Oh, before you delete the band, it'll delete all these gigs", then the user chooses confirm and so on.
I need a query that deletes the band, then deletes the gigs where gigs.bandID = bands.bandID, and then deletes the assigns where assigns.gigID = gigs.gigID.
I've worked out the SELECT statement and this displays the record I want to delete from the assigns table by feeding it the bandid.
SELECT assigns.*
FROM bands INNER JOIN
gigs ON bands.bandid = gigs.bandid INNER JOIN
gigsaccass ON gigs.gigid = gigsaccass.gigid AND bands.bandid = 91
But how do I create a DELETE statement from this?
Upvotes: 1
Views: 3223
Reputation: 1216
There are two ways that this can be done, one as has been mentioned is a Cascading Delete
. The other would be to effectively recreate a cascading deletion by use of several queries. Personally I prefer the second option, as it allows you a little bit more control over your data. Utilizing cascading deletions (especially in a production environment) can lead to rather disastrous consequences if you're not extremely careful. Undoing a single record deletion can be fairly easy (if it's a simple table), undoing a cascading delete that inadvertently hits against 20 different tables is all but impossible without a database backup.
Upvotes: 2
Reputation: 2785
There are a bunch of ways you could go about it, but this is the route I'd go if you don't want to do the ON DELETE CASCADE
constraint option...
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
Upvotes: 2
Reputation: 13949
Cascading deletes are nice and easy.. you just need to create your foreign keys a certain way.
-- 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
make sure you delete the current foreign key first if you have one..
another way is create triggers.. in particular, Instead of Delete
triggers
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
Upvotes: 0
Reputation: 395
As jae555 says, I would say that the ON DELETE CASCADE trigger is the way to go.
Upvotes: 0