Database: SQL Server, 2017.
I need to enforce certain business rules in a trigger. Now, before you tell me to use a foreign key, please know that the rules are too complicated to be enforced by foreign keys. With that out of the way, let me get to the meat of my question:
Is this the correct way to rollback/cancel the insert/update in a trigger if a business rule is violated:
CREATE TRIGGER [dbo].[MyTestTrigger]
ON [dbo].[MyTestTable]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF TRIGGER_NESTLEVEL(OBJECT_ID('[dbo].[MyTestTrigger]')) > 1
BEGIN
RETURN;
END
if (condition_is_true) begin
;throw 51000, 'Bad data Message.',1;
end
end
I know my question seems simple, but I stumbled on this "treatise" on error handling in SQL Server. After skimming through it, I came away with the impression that error handing is extremely complicated. One thing I am confused about is, do I need to explicitly call the rollback
statement before/after the throw
statement? Or will the throw
itself rollback the update/insert. From my testing, the throw
itself rolls back the update/insert. However, in Microsoft's own documentation on triggers, the rollback
statement is included:
USE AdventureWorks2022;
GO
IF OBJECT_ID ('Purchasing.LowCredit','TR') IS NOT NULL
DROP TRIGGER Purchasing.LowCredit;
GO
-- This trigger prevents a row from being inserted in the Purchasing.PurchaseOrderHeader table
-- when the credit rating of the specified vendor is set to 5 (below average).
CREATE TRIGGER Purchasing.LowCredit ON Purchasing.PurchaseOrderHeader
AFTER INSERT
AS
IF (ROWCOUNT_BIG() = 0)
RETURN;
IF EXISTS (SELECT 1
FROM inserted AS i
JOIN Purchasing.Vendor AS v
ON v.BusinessEntityID = i.VendorID
WHERE v.CreditRating = 5
)
BEGIN
RAISERROR ('A vendor''s credit rating is too low to accept new
purchase orders.', 16, 1);
ROLLBACK TRANSACTION;
RETURN
END;
Is the inclusion of rollback
really necessary?