MultiRow zagadnienia dotyczące DML wyzwalaczy
Podczas pisania kodu dla wyzwalacz DML, uznają, że oświadczenie, że powoduje uruchomienie wyzwalacza INSTEAD można pojedynczej instrukcja, która dotyczy wielu wierszy danych, zamiast jednego wiersza.To zachowanie jest wspólne wyzwalaczy aktualizacji i usuwania, ponieważ często oświadczenia te wpływają na wiele wierszy.Zachowanie jest mniej popularne, WSTAW wyzwalaczy, ponieważ podstawowe instrukcja INSERT dodaje pojedynczy wiersz.Jednak ponieważ wyzwalacza WSTAWIENIA można wyzwolone przez INSERT INTO (table_name) instrukcja SELECT wstawiania wielu wierszy może powodować wywołanie jednego wyzwalacza.
MultiRow zagadnienia są szczególnie ważne, gdy funkcja wyzwalacz DML jest automatycznie ponownie obliczać wartości podsumowań z jednej tabela i zapisać wyniki w innym ciągłego tallies.
Ostrzeżenie
Nie zaleca się używania kursorów w wyzwalaczy, potencjalnie może ograniczyć wydajność.Aby zaprojektować wyzwalacz, który dotyczy wielu zestaw wierszy, użyj logiki oparte na zestawie zestaw wierszy zamiast kursorów.
Przykłady
DML Wyzwalaczy w poniższych przykładach są przeznaczone do przechowywania sumy kolumna w innej tabela, z AdventureWorks2008R2 przykładowej bazy danych.
A.Przechowywanie sumę dla wstawianie pojedynczego wiersza
Pierwszą wersja wyzwalacz DML działa dobrze dla pojedynczego wiersza wstawiania, gdy wiersz danych jest ładowany do PurchaseOrderDetail tabela.Fires instrukcja INSERT wyzwalacz DML i nowy wiersz jest ładowany do dodaje się tabela czas wykonywania wyzwalacza.UPDATE Odczytów instrukcja LineTotal kolumna wartość wiersza i dodaje tę wartość do istniejącej wartości w SubTotal kolumna w PurchaseOrderHeader tabela.WHERE klauzula, zapewnia zaktualizowanych wierszy w PurchaseOrderDetail tabela odpowiedników PurchaseOrderID wiersza w dodaje się tabeli.
-- Trigger is valid for single-row inserts.
USE AdventureWorks2008R2;
GO
CREATE TRIGGER NewPODetail
ON Purchasing.PurchaseOrderDetail
AFTER INSERT AS
UPDATE PurchaseOrderHeader
SET SubTotal = SubTotal + LineTotal
FROM inserted
WHERE PurchaseOrderHeader.PurchaseOrderID = inserted.PurchaseOrderID ;
B.Przechowywanie sumę dla jednego wiersza lub multirow Wstaw
Do wstawiania multirow wyzwalacz DML w przykładzie a może nie działać poprawnie; Wyrażenie po prawej stronie wyrażenia przypisania w instrukcja UPDATE (SubTotal + LineTotal) mogą być tylko jedną wartość, nie listę wartości.Dlatego wpływ wyzwalacz jest, aby pobrać wartość dowolnego pojedynczego wiersza w dodaje się tabela i dodać tę wartość do istniejącego SubTotal wartość w PurchaseOrderHeader tabela dla określonego PurchaseOrderID wartości.Ta operacja może nie mieć oczekiwany skutek, jeśli pojedyncza PurchaseOrderID wystąpił więcej niż jedną wartość czas w dodaje się tabela.
Aby poprawnie zaktualizować PurchaseOrderHeader tabela wyzwalacz musi umożliwić szansy wielu wierszy dodaje tabela.Można to zrobić za pomocą SUM Funkcja, która oblicza sumę LineTotal dla grupy wierszy w dodaje się tabela dla każdego PurchaseOrderID.SUM funkcja znajduje się w skorelowane podzapytanie ( SELECT instrukcja w nawiasach).podzapytanie to zwraca jedną wartość dla każdego PurchaseOrderID w dodaje tabela, która odpowiada lub skorelowane z PurchaseOrderID w PurchaseOrderHeader tabela.
-- Trigger is valid for multirow and single-row inserts.
USE AdventureWorks2008R2;
GO
CREATE TRIGGER NewPODetail2
ON Purchasing.PurchaseOrderDetail
AFTER INSERT AS
UPDATE PurchaseOrderHeader
SET SubTotal = SubTotal +
(SELECT SUM(LineTotal)
FROM inserted
WHERE PurchaseOrderHeader.PurchaseOrderID
= inserted.PurchaseOrderID)
WHERE PurchaseOrderHeader.PurchaseOrderID IN
(SELECT PurchaseOrderID FROM inserted);
Ten wyzwalacz również działa poprawnie w wstawianie pojedynczego wiersza; Suma LineTotal wartość kolumna jest sumą pojedynczego wiersza.Jednakże z tego wyzwalacza skorelowane podzapytanie i IN operator, który jest używany w WHERE klauzula wymagają dodatkowego przetwarzania z SQL Server.Jest to konieczne w przypadku wstawiania pojedynczego wiersza.
C.Przechowywanie sumę na podstawie typu Wstaw
Można zmienić wyzwalacz użycia metoda optymalną liczbę wierszy.Na przykład @@ROWCOUNT funkcja może być użyta w logice wyzwalacza odróżnić jeden multirow Wstaw.
-- Trigger valid for multirow and single row inserts
-- and optimal for single row inserts.
USE AdventureWorks2008R2;
GO
CREATE TRIGGER NewPODetail3
ON Purchasing.PurchaseOrderDetail
FOR INSERT AS
IF @@ROWCOUNT = 1
BEGIN
UPDATE PurchaseOrderHeader
SET SubTotal = SubTotal + LineTotal
FROM inserted
WHERE PurchaseOrderHeader.PurchaseOrderID = inserted.PurchaseOrderID
END
ELSE
BEGIN
UPDATE PurchaseOrderHeader
SET SubTotal = SubTotal +
(SELECT SUM(LineTotal)
FROM inserted
WHERE PurchaseOrderHeader.PurchaseOrderID
= inserted.PurchaseOrderID)
WHERE PurchaseOrderHeader.PurchaseOrderID IN
(SELECT PurchaseOrderID FROM inserted)
END;