Opret triggere
Triggere er specielle lagrede procedurer, der automatisk udføres, når specifikke hændelser opstår i din database. Du definerer triggere til at opretholde dataintegritet, håndhæve forretningsregler og automatisere databaseoperationer uden at kræve applikationskode.
Forstå triggerens grundlæggende principper
En trigger reagerer på dataændringer eller skemaændringer i din database. Når du opretter en trigger, angiver du den begivenhed, der aktiverer den, og de handlinger, den udfører.
Triggere kører automatisk. I modsætning til stored procedures, som du kalder eksplicit, udløser fire som svar på INSERT, UPDATE, DELETE, eller DDL-sætninger. Denne automatiske udførelse gør dem kraftfulde til at håndhæve regler, der skal gælde konsekvent på tværs af alle dataændringer.
SQL Server understøtter to hovedkategorier af triggere: DML (Data Manipulation Language) triggere og DDL (Data Definition Language) triggere. DML-triggere reagerer på ændringer i tabeldata, mens DDL-triggere reagerer på skemaændringer som CREATE, ALTER, eller DROP sætninger.
Opret DML-triggere til dataændringer
DML-triggere overvåger og reagerer på ændringer i data i tabeller eller visninger. Du definerer dem enten som EFTER triggere eller I STEDET FOR UDLØSERE .
AFTER triggere udføres, efter at trigger-sætningen er fuldført. Databasen udfører først dataændringen og kører derefter triggerkoden. Du bruger AFTER-triggere til at validere ændringer, opdatere relaterede tabeller eller logge ændringer:
CREATE TRIGGER tr_UpdateInventory
ON Sales.OrderDetails
AFTER INSERT
AS
BEGIN
UPDATE Inventory.Products
SET QuantityInStock = QuantityInStock - i.Quantity
FROM Inventory.Products p
INNER JOIN inserted i ON p.ProductID = i.ProductID;
END;
INSTEAD OF-triggere erstatter den oprindelige dataændringserklæring. Triggerkoden udfører i stedet for INSERT, UPDATE, eller DELETE operationen. Du bruger INSTEAD OF-triggere til at ændre visninger, der normalt ikke ville acceptere direkte ændringer, eller til at implementere kompleks forretningslogik:
CREATE TRIGGER tr_UpdateOrderView
ON Sales.OrderSummaryView
INSTEAD OF UPDATE
AS
BEGIN
UPDATE Sales.Orders
SET OrderStatus = i.OrderStatus,
ModifiedDate = GETDATE()
FROM Sales.Orders o
INNER JOIN inserted i ON o.OrderID = i.OrderID;
END;
Med DML-triggere får du adgang til de indsatte og slettede pseudo-tabeller. Disse midlertidige tabeller gemmer kopier af de berørte rækker.
INSERT Operationer udfylder den indsatte tabel, DELETE operationer udfylder den slettede tabel, og UPDATE operationer udfylder begge tabeller med gamle værdier i slettet og nye værdier i indsat.
Implementer triggere for specifikke hændelser
Du angiver, hvilke dataændringsbegivenheder der aktiverer din trigger. En enkelt trigger kan reagere på flere hændelser ved at kombinere INSERT, UPDATE, og DELETE i triggerdefinitionen.
For præcis kontrol opretter du separate triggere for hver operation. Denne tilgang forenkler din kode og gør dine triggere lettere at vedligeholde:
CREATE TRIGGER tr_LogPriceChanges
ON Products.Catalog
AFTER UPDATE
AS
BEGIN
IF UPDATE(Price)
BEGIN
INSERT INTO Audit.PriceHistory (ProductID, OldPrice, NewPrice, ChangeDate)
SELECT d.ProductID, d.Price, i.Price, GETDATE()
FROM deleted d
INNER JOIN inserted i ON d.ProductID = i.ProductID
WHERE d.Price <> i.Price;
END;
END;
Samtidig kan du kombinere begivenheder, når den samme logik gælder for flere operationer. For eksempel kunne du oprette en enkelt audit-trigger, der reagerer på INSERT, UPDATE, og DELETE:
CREATE TRIGGER tr_AuditEmployeeChanges
ON HR.Employees
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
DECLARE @Operation NVARCHAR(10);
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)
SET @Operation = 'INSERT';
ELSE IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
SET @Operation = 'UPDATE';
ELSE
SET @Operation = 'DELETE';
INSERT INTO Audit.EmployeeLog (EmployeeID, Operation, ChangeDate)
SELECT COALESCE(i.EmployeeID, d.EmployeeID), @Operation, GETDATE()
FROM inserted i
FULL OUTER JOIN deleted d ON i.EmployeeID = d.EmployeeID;
END;
Funktionen UPDATE() hjælper dig med at afgøre, hvilke kolonner der er ændret. Du tjekker specifikke kolonner for at undgå unødvendig behandling, når kun visse felter betyder noget for din forretningslogik.
Anvend bedste praksis for triggeren
Triggere påvirker databasens ydeevne, fordi de udføres ved hver kvalificerende operation. Du skriver effektiv triggerkode for at minimere påvirkningen på transaktionsgennemstrømningen.
Hold din trigger-logik fokuseret og minimal. Udfør kun nødvendige operationer i trigger-kroppen. For komplekse eller tidskrævende operationer kan du overveje at logge hændelsesdetaljerne og behandle dem asynkront gennem et separat job:
CREATE TRIGGER tr_QueueLargeOrders
ON Sales.Orders
AFTER INSERT
AS
BEGIN
INSERT INTO Processing.OrderQueue (OrderID, TotalAmount, QueuedDate)
SELECT OrderID, TotalAmount, GETDATE()
FROM inserted
WHERE TotalAmount > 10000;
END;
Undgå rekursive operationer, hvor en aftrækkermodifikation får den samme aftrækker til at affyres igen. Indstil databaseindstillingen RECURSIVE_TRIGGERS korrekt og design dine triggere for at forhindre endeløse løkker.
Håndter fejl korrekt inden for triggere. Transaktionsadfærd afhænger af din fejlhåndtering. Hvis en trigger støder på en fejl, og du ikke håndterer den, ruller SQL Server både triggeren og den oprindelige sætning tilbage:
CREATE TRIGGER tr_ValidateOrderDate
ON Sales.Orders
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT * FROM inserted WHERE OrderDate > GETDATE())
BEGIN
THROW 50001, 'Order date cannot be in the future', 1;
END;
END;
Dokumentér dine triggere grundigt. Andre udviklere skal forstå, hvorfor triggere eksisterer, og hvad de gør, da de udfører usynligt under normale databaseoperationer.
Nu hvor du forstår, hvordan man skaber og implementerer triggere, er du klar til at udforske, hvordan de integreres med andre programmerbarhedsobjekter for at bygge omfattende databaseløsninger.