Aracılığıyla paylaş


Birden Çok Veri Satırını İşleyecek DML Tetikleyicileri Oluşturma

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen ÖrneğiMicrosoft Fabric'te SQL veritabanı

DML tetikleyicisinin kodunu yazarken, tetikleyicinin tetiklemesine neden olan deyimin tek bir satır yerine birden çok veri satırını etkileyen tek bir deyim olabileceğini düşünün. Bu davranış, UPDATE ve DELETE tetikleyicileri için yaygındır çünkü bu deyimler sıklıkla birden çok satırı etkiler. Temel INSERT deyimi yalnızca tek bir satır eklediğinden, INSERT tetikleyicileri için davranış daha az yaygındır. Ancak INSERT tetikleyicisi INSERT INTO (table_name) SELECT deyimi tarafından tetiklendiğinden, birçok satırın eklenmesi tek bir tetikleyici çağrısına neden olabilir.

DML tetikleyicisinin işlevi, bir tablodaki özet değerleri otomatik olarak yeniden hesaplamak ve sonuçları devam eden sayımlar için başka bir tabloda depolamak olduğunda, çok satırlı işlemler özellikle önemlidir.

Not

İmleçlerin performansı düşürebileceği için tetikleyicilerde kullanılması önerilmez. Birden çok satırı etkileyen bir tetikleyici tasarlamak için imleçler yerine satır kümesi tabanlı mantık kullanın.

Örnekler

Aşağıdaki örneklerde yer alan DML tetikleyicileri, bir sütunun çalışan toplamını AdventureWorks2025 örnek veritabanının başka bir tablosunda depolamak için tasarlanmıştır.

A. Tek satırlı ekleme için anlık toplamı depolama

DML tetikleyicisinin ilk sürümü, PurchaseOrderDetail tablosuna bir veri satırı yüklendiğinde tek satırlı ekleme için iyi çalışır. INSERT deyimi DML tetikleyicisini tetikler ve yeni satır, tetikleyici yürütme süresi boyunca eklenen tablosuna yüklenir. UPDATE deyimi, satırın LineTotal sütun değerini okur ve bu değeri SubTotal tablosundaki PurchaseOrderHeader sütunundaki mevcut değere ekler. WHERE yan tümcesi, PurchaseOrderDetail tablosundaki güncellenecek satırın, eklenmiş PurchaseOrderID tablosundaki satırın ile eşleşmesini sağlar.

-- Trigger is valid for single-row inserts.  
USE AdventureWorks2022;  
GO  
CREATE TRIGGER NewPODetail  
ON Purchasing.PurchaseOrderDetail  
AFTER INSERT AS  
   UPDATE PurchaseOrderHeader  
   SET SubTotal = SubTotal + LineTotal  
   FROM inserted  
   WHERE PurchaseOrderHeader.PurchaseOrderID = inserted.PurchaseOrderID ;  

B. Çok satırlı veya tek satırlı ekleme için işleyen toplamı saklama

Çok satırlı bir insert için, örnek A'daki DML tetikleyicisi doğru çalışmayabilir; UPDATE ifadesinde (SubTotal + LineTotal) atama ifadesinin sağında yer alan ifade, değerler listesi değil, yalnızca tek bir değer olabilir. Bu nedenle tetikleyicinin etkisi, eklenen tablosundaki herhangi bir satırdan bir değer almak ve bu değeri belirli bir SubTotal değeri için PurchaseOrderHeader tablosundaki mevcut PurchaseOrderID değerine eklemektir. Eklenen PurchaseOrderID tablosunda tek bir değeri birden fazla kez oluştuysa bu işlem beklenen etkiye sahip olmayabilir.

PurchaseOrderHeader tablosunu doğru şekilde güncelleştirmek için tetikleyicinin eklenen tablosunda birden çok satıra izin vermesi gerekir. Bunu, her SUMiçin eklenen LineTotal tablosundaki bir satır grubu için toplam hesaplayan PurchaseOrderID işlevini kullanarak yapabilirsiniz. SUM işlevi bağıntılı bir alt sorguya (parantez içindeki SELECT deyimi) dahil edilir. Bu alt sorgu, PurchaseOrderID tablosundaki her için, PurchaseOrderID tablosundaki bir PurchaseOrderHeader ile eşleşen veya ilişkilendirilen tek bir değer döndürmektedir.

-- Trigger is valid for multirow and single-row inserts.  
USE AdventureWorks2022;  
GO  
CREATE TRIGGER NewPODetail2  
ON Purchasing.PurchaseOrderDetail  
AFTER INSERT AS  
   UPDATE Purchasing.PurchaseOrderHeader  
   SET SubTotal = SubTotal +   
      (SELECT SUM(LineTotal)  
      FROM inserted  
      WHERE PurchaseOrderHeader.PurchaseOrderID  
       = inserted.PurchaseOrderID)  
   WHERE PurchaseOrderHeader.PurchaseOrderID IN  
      (SELECT PurchaseOrderID FROM inserted);  

Bu tetikleyici aynı zamanda tek satırlı bir eklemede de düzgün çalışır; LineTotal değer sütununun toplamı tek bir satırın toplamıdır. Ancak bu tetikleyiciyle, IN yan tümcesinde kullanılan bağıntılı alt sorgu ve WHERE işleci SQL Server'dan ek işleme gerektirir. Bu, tek satırlı ekleme için gereksizdir.

C. Ekleme türüne göre çalışan toplamı depolama

Tetikleyiciyi, satır sayısı için en uygun yöntemi kullanacak şekilde değiştirebilirsiniz. Örneğin, @@ROWCOUNT işlevi tetikleyicinin mantığında tek satırlı ve çok satırlı ekleme arasında ayrım yapmak için kullanılabilir.

-- Trigger valid for multirow and single row inserts  
-- and optimal for single row inserts.  
USE AdventureWorks2022;  
GO  
CREATE TRIGGER NewPODetail3  
ON Purchasing.PurchaseOrderDetail  
FOR INSERT AS  
IF @@ROWCOUNT = 1  
BEGIN  
   UPDATE Purchasing.PurchaseOrderHeader  
   SET SubTotal = SubTotal + LineTotal  
   FROM inserted  
   WHERE PurchaseOrderHeader.PurchaseOrderID = inserted.PurchaseOrderID  
END  
ELSE  
BEGIN  
      UPDATE Purchasing.PurchaseOrderHeader  
   SET SubTotal = SubTotal +   
      (SELECT SUM(LineTotal)  
      FROM inserted  
      WHERE PurchaseOrderHeader.PurchaseOrderID  
       = inserted.PurchaseOrderID)  
   WHERE PurchaseOrderHeader.PurchaseOrderID IN  
      (SELECT PurchaseOrderID FROM inserted)  
END;  

Ayrıca Bkz.

DML Tetikleyicileri