Lag triggere
Triggere er spesielle lagrede prosedyrer som automatisk utføres når spesifikke hendelser skjer i databasen din. Du definerer triggere for å opprettholde dataintegritet, håndheve forretningsregler og automatisere databaseoperasjoner uten å kreve applikasjonskode.
Forstå triggerens grunnleggende prinsipper
En trigger reagerer på dataendringer eller skjemaendringer i databasen din. Når du oppretter en trigger, spesifiserer du hendelsen som aktiverer den og handlingene den utfører.
Triggere kjører automatisk. I motsetning til lagrede prosedyrer som du kaller eksplisitt, utløser fire som svar på INSERT, UPDATE, DELETE, eller DDL-setninger. Denne automatiske utførelsen gjør dem kraftige for å håndheve regler som må anvendes konsekvent på tvers av alle dataendringer.
SQL Server støtter to hovedkategorier av triggere: DML (Data Manipulation Language) triggere og DDL (Data Definition Language) triggere. DML-triggere svarer på endringer i tabelldata, mens DDL-triggere svarer på skjemaendringer som CREATE, ALTER, eller DROP setninger.
Lag DML-triggere for datamodifikasjoner
DML-triggere overvåker og reagerer på endringer i data i tabeller eller visninger. Du definerer dem enten som ETTER-triggere eller I STEDET FOR triggere.
AFTER-triggere utfører etter at trigger-setningen er fullført. Databasen utfører først dataendringen, og kjører deretter triggerkoden. Du bruker AFTER-triggere for å validere endringer, oppdatere relaterte tabeller eller loggføre endringer:
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 opprinnelige dataendringssetningen. Triggerkoden utføres i stedet for INSERT, UPDATE, eller DELETE operasjonen. Du bruker INSTEAD OF-triggere for å endre visninger som normalt ikke ville akseptert direkte endringer, eller for å implementere kompleks forretningslogikk:
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 tilgang til de innsatte og slettede pseudo-tabellene. Disse midlertidige tabellene lagrer kopier av de berørte radene.
INSERT Operasjoner fyller ut den innsatte tabellen, DELETE operasjoner fyller den slettede tabellen, og UPDATE operasjoner fyller begge tabellene med gamle verdier i slettet og nye verdier i innsatt.
Implementer triggere for spesifikke hendelser
Du spesifiserer hvilke dataendringshendelser som aktiverer triggeren din. En enkelt trigger kan svare på flere hendelser ved å kombinere INSERT, UPDATE, og DELETE i triggerdefinisjonen.
For presis kontroll lager du separate triggere for hver operasjon. Denne tilnærmingen forenkler koden din og gjør triggerne dine lettere å vedlikeholde:
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 hendelser når samme logikk gjelder for flere operasjoner. For eksempel kan du lage en enkelt revisjonstrigger som svarer 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;
Funksjonen UPDATE() hjelper deg å avgjøre hvilke kolonner som er endret. Du sjekker spesifikke kolonner for å unngå unødvendig behandling når bare visse felt er viktige for forretningslogikken din.
Bruk beste praksis for triggere
Triggere påvirker databaseytelsen fordi de utføres ved hver kvalifiserende operasjon. Du skriver effektiv triggerkode for å minimere påvirkningen på transaksjonsgjennomstrømningen.
Hold trigger-logikken fokusert og minimal. Utfør kun nødvendige operasjoner innenfor triggerkroppen. For komplekse eller tidkrevende operasjoner, vurder å loggføre hendelsesdetaljene og behandle dem asynkront gjennom en separat jobb:
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;
Unngå rekursive operasjoner der en modifikasjon av avtrekkeren får samme avtrekker til å fyre av igjen. Sett RECURSIVE_TRIGGERS databasevalget riktig og design triggerne dine for å unngå endeløse løkker.
Håndter feil riktig innenfor triggere. Transaksjonsatferd avhenger av feilbehandlingen din. Hvis en trigger får en feil og du ikke håndterer den, ruller SQL Server tilbake både triggeren og den opprinnelige setningen:
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;
Dokumenter dine triggere grundig. Andre utviklere må forstå hvorfor triggere eksisterer og hva de gjør, siden de utføres usynlig under normale databaseoperasjoner.
Nå som du forstår hvordan du lager og implementerer triggere, er du klar til å utforske hvordan de integreres med andre programmerbare objekter for å bygge omfattende databaseløsninger.