I have a table Universities and a table Cities. There is a m:n relationship between them, so the relationship is saved in a further table called CityUniversities. Now I wanted to write a trigger which deletes all relations between the tables Cities and Universities when deleting a university from Universities. However it’s not working. I always receive the following error message when trying to delete a University:
“Msg 547, Level 16, State 0, Line 2
The DELETE statement conflicted with the REFERENCE constraint “FK_CityUniversities_Universities”. The conflict occurred in database “Alumni_Dev”, table “dbo.CityUniversities”, column ‘UniversityId’.
The statement has been terminated.”
That’s the trigger (for table Universities) which I have implemented and succesfully executed:
USE [Alumni_Dev]
GO
/****** Object: Trigger [dbo].[deleteUni] Script Date: 05/02/2012 11:42:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[deleteUni]
ON [dbo].[Universities]
FOR DELETE
AS
DECLARE @UniId int
SELECT @UniId = (SELECT UniversityId FROM deleted)
BEGIN
--Remove constraints
DELETE FROM dbo.CityUniversities WHERE UniversityId = @UniId;
END
I already compared my solution with several references, however I can’t find anything that could be wrong. Could it be that there are any wrong settings in one of the affected tables?
I’d be happy to hear any suggestions.
I finally solved my problem with the following trigger (thx to Nikola):
ALTER TRIGGER [dbo].[deleteUni]
ON [dbo].[Universities]
INSTEAD OF DELETE
AS
DECLARE @UniId int
SELECT @UniId = UniversityId FROM deleted
BEGIN
--Remove constraints
DELETE FROM dbo.CityUniversities WHERE UniversityId = @UniId;
DELETE FROM dbo.Universities WHERE UniversityId = @UniId;
END
Trigger cannot be used to delete orphaned records from other tables because constraints are checked before trigger gets executed. You should set up ON DELETE CASCADE instead.
You might use INSTEAD OF trigger also if you want to perform some checking before deletion, but don’t forget to add
delete Universities where ...at the end of a trigger to actually delete record.Two points about triggers:
Don’t treat deleted and inserted tables as if they contain one record only. There will be nasty surprises when you try to delete two universities. You should rather join a table you work with with deleted or inserted tables, using them as filter, or use exists:
or
Oh, and
is equivalent to: