Skapa utlösare

Fullbordad

Utlösare är särskilda lagrade procedurer som körs automatiskt när specifika händelser inträffar i databasen. Du definierar utlösare för att upprätthålla dataintegritet, framtvinga affärsregler och automatisera databasåtgärder utan att kräva kod på programnivå.

Förstå grunderna för utlösare

En utlösare svarar på dataändringar eller schemaändringar i databasen. När du skapar en utlösare anger du den händelse som aktiverar den och vilka åtgärder den utför.

Triggare körs automatiskt. Till skillnad från lagrade procedurer som du anropar explicit, utlöses triggers som svar på INSERT, UPDATE, DELETE eller DDL-instruktioner. Den här automatiska exekveringen gör dem kraftfulla för att upprätthålla reglerna som måste tillämpas konsekvent vid alla dataändringar.

SQL Server stöder två huvudkategorier av utlösare: DML-utlösare (datamanipuleringsspråk) och DDL-utlösare (datadefinitionsspråk ). DML-utlösare svarar på ändringar i tabelldata, medan DDL-utlösare svarar på schemaändringar som CREATE, ALTEReller DROP -instruktioner.

Skapa DML-utlösare för dataändringar

DML utlöser övervakning och svar på dataändringar i tabeller eller vyer. Du definierar dem som antingen AFTER-utlösare eller INSTEAD OF-utlösare.

AFTER-utlösare körs när utlösande instruktionen har slutförts. Databasen utför först dataändringen och kör sedan utlösarkoden. Du använder AFTER-utlösare för att verifiera ändringar, uppdatera relaterade tabeller eller loggändringar:

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;

I STÄLLET för utlösare ersätter den ursprungliga datamodifieringskommandot. Utlösarkoden körs i stället för åtgärden INSERT, UPDATEeller DELETE . Du använder i stället för utlösare för att ändra vyer som normalt inte accepterar direkta ändringar eller för att implementera komplex affärslogik:

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-utlösare kommer du åt de infogade och borttagna pseudotabellerna. Dessa temporära tabeller lagrar kopior av de berörda raderna. INSERT åtgärder fyller i den infogade tabellen, DELETE åtgärder fyller i den borttagna tabellen och UPDATE åtgärder fyller båda tabellerna med gamla värden i borttagna och nya värden i infogade.

Implementera utlösare för specifika händelser

Du anger vilka dataändringshändelser som aktiverar utlösaren. En enskild utlösare kan svara på flera händelser genom att kombinera INSERT, UPDATEoch DELETE i utlösardefinitionen.

För exakt kontroll skapar du separata utlösare för varje åtgärd. Den här metoden förenklar koden och gör utlösarna enklare att underhålla:

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;

Samtidigt kan du kombinera händelser när samma logik gäller för flera åtgärder. Du kan till exempel skapa en enda granskningsutlösare INSERTsom svarar på , UPDATEoch 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 att avgöra vilka kolumner som har ändrats. Du kan kontrollera specifika kolumner för att undvika onödig bearbetning när endast vissa fält är viktiga för din affärslogik.

Tillämpa metodtips för utlösare

Utlösare påverkar databasprestanda eftersom de körs med varje kvalificerande åtgärd. Du skriver effektiv utlösarkod för att minimera påverkan på transaktionsdataflödet.

Håll din utlösarlogik fokuserad och minimal. Kör endast nödvändiga åtgärder i utlösarens kropp. För komplexa eller tidskrävande åtgärder bör du överväga att logga händelseinformationen och bearbeta dem asynkront via ett 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;

Undvik rekursiva åtgärder där en utlösarändring gör att samma utlösare utlöses igen. Ange databasalternativet RECURSIVE_TRIGGERS på rätt sätt och utforma dina utlösare för att förhindra oändliga loopar.

Hantera fel korrekt inom utlösare. Transaktionsbeteendet beror på felhanteringen. Om en utlösare stöter på ett fel och du inte hanterar det återställer SQL Server både utlösaren och den ursprungliga instruktionen:

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;

Dokumentera utlösarna noggrant. Andra utvecklare måste förstå varför utlösare finns och vad de gör, eftersom de körs osynligt under normala databasåtgärder.

Nu när du förstår hur du skapar och implementerar utlösare är du redo att utforska hur de integreras med andra programmeringsobjekt för att skapa omfattande databaslösningar.