Upload
oswald-jackson
View
271
Download
2
Embed Size (px)
Citation preview
ALTER TRIGGER TriggerOne ON Person AFTER UPDATE AS SELECT D.LastName + ‘ changed to ’ + I.LastName FROM Inserted AS I INNER JOIN Deleted AS D ON I.PersonID = D.PersonID; GO UPDATE Person SET LastName = ‘Carter’ WHERE LastName = ‘Johnson’; Result: ------------------------------------------ Johnson changed to Carter Johnson changed to Carter (2 row(s) affected)
Your business rule needs to reference data in a separate table.
Your business rule needs to check the delta (difference between before and after) of an UPDATE.
You require a customized error message. Using Triggers for Custom Error Messages Updating summary information Feeding de-normalized tables for
reporting Setting condition flags
Complex data validationWriting data-audit trailsMaintaining modified date columnsEnforcing custom referential-
integrity checks and cascading deletes
CREATE TRIGGER Sales.SalesOrderDetailNotDiscontinued
ON Sales.SalesOrderDetail FOR INSERT, UPDATE AS IF EXISTS( SELECT ‘True’ FROM Inserted i JOIN Production.Product p ON i.ProductID =
p.ProductID WHERE p.DiscontinuedDate IS NOT NULL) BEGIN RAISERROR(‘Order Item is discontinued.
Transaction Failed.’,16,1) ROLLBACK TRAN END
UPDATE Production.ProductSET DiscontinuedDate = ‘01-01-
2008’WHERE ProductID = 680
INSERT INTO Sales.SalesOrderDetailVALUES (43659, ‘4911-403C-98’, 1, 680, 1,
1431.50,0.00, NEWID(), GETDATE())
Msg 50000, Level 16, State 1, Procedure SalesOrderDetailNotDiscontinued, Line 14
Order Item is discontinued. Transaction Failed.
Msg 3609, Level 16, State 1, Line 1The transaction ended in the trigger.
The batch has been aborted.
CREATE TRIGGER <trigger name> ON [<schema name>.]<table or view
name> [WITH ENCRYPTION | EXECUTE AS
<CALLER | SELF | <user> >] {{{FOR|AFTER} <[DELETE] [,] [INSERT]
[,] [UPDATE]>} |INSTEAD OF} [WITH APPEND] [NOT FOR REPLICATION] AS < <sql statements> | EXTERNAL NAME
<assembly method specifier> >
CREATE TRIGGER Production.ProductIsRationed ON Production.ProductInventory FOR UPDATE AS IF EXISTS( SELECT ‘True’ FROM Inserted i JOIN Deleted d ON i.ProductID = d.ProductID AND i.LocationID = d.LocationID WHERE (d.Quantity - i.Quantity) > d.Quantity /
2 AND d.Quantity – i.Quantity > 0) BEGIN RAISERROR(‘Cannot reduce stock by more than
50%% at once.’,16,1) ROLLBACK TRAN END
sp_settriggerorder[@triggername =] ‘<trigger name>’,
[@order =] ‘{FIRST|LAST|NONE}’, [@stmttype =] ‘{INSERT|UPDATE|
DELETE}’ [, [@namespace =] {‘DATABASE’ |
‘SERVER’ | NULL} ]
Keep It Short and SweetDon’t Forget Triggers When
Choosing IndexesTry Not to Roll Back Within Triggers
ALTER TRIGGER Production.ProductIsRationed ON Production.ProductInventory FOR UPDATE AS IF UPDATE(Quantity) BEGIN IF EXISTS( SELECT ‘True’ FROM Inserted i JOIN Deleted d ON i.ProductID = d.ProductID AND i.LocationID = d.LocationID WHERE (d.Quantity - i.Quantity) > d.Quantity / 2 AND d.Quantity > 0 ) BEGIN RAISERROR(‘Cannot reduce stock by more than 50%% at
once.’,16,1) ROLLBACK TRAN END END