Yes, if the trigger encounters an error (internally or through calling some external procedure) and rolls back the transaction, it will roll back the whole transaction, including whatever UPDATE
caused the trigger to fire in the first place. There are multiple ways to get around this, if it is not the behavior you want:
use TRY / CATCH
to absorb any errors form the external procedure, or move the procedure logic into the trigger, or add proper error handling to the stored procedure so that, if you don't care that an error happened there, it doesn't bubble up and roll back everything.
use an INSTEAD OF
trigger - combined with TRY / CATCH
(or possibly committing your own UPDATE
first), you should be able to update the table without caring whether the external stored procedure fails.
Example of the INSTEAD OF
trigger:
USE tempdb;
GO
CREATE TABLE dbo.flooblat(id INT PRIMARY KEY, name VARCHAR(32));
INSERT dbo.flooblat(id,name) VALUES(1, 'Bob');
GO
CREATE PROCEDURE dbo.oh_my
AS
SELECT 1/0;
GO
CREATE TRIGGER dbo.trFlooblat
ON dbo.flooblat
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE f SET f.name = i.name
FROM dbo.flooblat AS f
INNER JOIN inserted AS i
ON f.id = i.id;
COMMIT TRANSACTION;
EXEC dbo.oh_my;
END
GO
UPDATE dbo.flooblat SET name = 'Frank';
GO
SELECT id, name FROM dbo.flooblat;
GO
Results:
Msg 8134, Level 16, State 1, Procedure oh_my
Divide by zero error encountered.
The statement has been terminated.
However, the SELECT
reveals that, even though an error occurred in the trigger, it happened after the UPDATE
was committed - so unlike an exception that occurs in an AFTER
trigger (without proper error handling), we were able to prevent the error from rolling back all of the work we've done.
id name
---- -----
1 Frank