I've got the following trigger on a table for a SQL Server 2008 database. It's recursing, so I need to stop it.
After I insert or update a record, I'm trying to simply update a single field on that table.
Here's the trigger :
ALTER TRIGGER [dbo].[tblMediaAfterInsertOrUpdate]
ON [dbo].[tblMedia]
BEFORE INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON
DECLARE @IdMedia INTEGER,
@NewSubject NVARCHAR(200)
SELECT @IdMedia = IdMedia, @NewSubject = Title
FROM INSERTED
-- Now update the unique subject field.
-- NOTE: dbo.CreateUniqueSubject is my own function.
-- It just does some string manipulation.
UPDATE tblMedia
SET UniqueTitle = dbo.CreateUniqueSubject(@NewSubject) +
CAST((IdMedia) AS VARCHAR(10))
WHERE tblMedia.IdMedia = @IdMedia
END
Can anyone tell me how I can prevent the trigger's insert from kicking off another trigger again?
I see three possibilities:
Disable trigger recursion:
This will prevent a trigger fired to call another trigger or calling itself again. To do this, execute this command:
Use a trigger INSTEAD OF UPDATE, INSERT
Using a
INSTEAD OF
trigger you can control any column being updated/inserted, and even replacing before calling the command.Control the trigger by preventing using IF UPDATE
Testing the column will tell you with a reasonable accuracy if you trigger is calling itself. To do this use the
IF UPDATE()
clause like:TRIGGER_NESTLEVEL
can be used to prevent recursion of a specific trigger, but it is important to pass the object id of the trigger into the function. Otherwise you will also prevent the trigger from firing when an insert or update is made by another trigger:From MSDN:
Reference: Avoiding recursive triggers
For completeness sake, I will add a few things. If you have a particular after trigger that you only want to run once, you can set it up to run last using sp_settriggerorder.
I would also consider if it might not be best to combine the triggers that are doing the recursion into one trigger.
You can have a separate NULLABLE column indicating whether the UniqueTitle was set.
Set it to true value in a trigger, and have the trigger do nothing if it's value is true in "INSERTED"
I think i got it :)
When the title is getting 'updated' (read: inserted or updated), then update the unique subject. When the trigger gets ran a second time, the uniquesubject field is getting updated, so it stop and leaves the trigger.
Also, i've made it handle MULTIPLE rows that get changed -> I always forget about this with triggers.