SQL Server – Merge Kullanımı (Aynı anda Insert,Delete ve Update)

Bu makalemizde MERGE kullanımını en geniş şekilde aynı anda hem Insert hem UPDATE hemde DELETE yapacağımız şekilde anlatımını sağlayacağız. Siz kendi yapınızda uygulayacağınız işlemi alarak MERGE işlemleriniz yapabilirsiniz.

Örneğimiz üzerinden giderek konuyu daha net anlamanızı sağlayacağım.

Bir ürün tablomuz olsun ve bu tabloda ürünler hakkında bilgi içeriğimiz bulunsun. Birde güncel ürünler tablomuz olsun ve bu da kaynak tablomuz olsun. Baktığınızda hedef tablomuz Product , kaynak tablomuzda UpdateProducts tablosu. Biz Kaynak tablomuzda ki bilgileri Hedef tablomuzda güncel tutmamız gerekmekte ve bunun için her defasında INSERT,UPDATE ve DELETE işlemleri uygulamamız gerekmekte.  Bu bizim ve sistem için tam bir eziyete dönüşebilir bu şekilde. Basit bir yapı olarak gözükebilir fakat işlem yoğunluğunuz arttıkça hantal bir yapı ve performance diplerde seyreder böyle bir yapıda. İşte bu noktada MERGE deyimi işin içine girmekte ve bir seferde bu üç işlemi MERGE deyimi ile nasıl yaparız onu göreceğiz.

SQL Server 2008 ile kullanımı başlayan bu komut Oracle ın UPDERT (Update ve Insert) komutuna benzerlik göstermektedir.UPSERT  ü basitçe açıklamak gerekirse  var olmayan satırı ekler ve var olanı günceller.

MERGE ifadesi temelde, belirttiğiniz koşulu temel alan ve kaynaktaki verilerin hedefte bulunup bulunmadığını temel alarak belirlenen bir kaynak sonuçtan verileri bir hedef tabloya birleştirir. Yeni SQL komutu, kaydın varlığına bağlı olarak koşullu INSERT, UPDATE ve DELETE komutlarının sırasını tek bir atomik ifadede birleştirir. Yeni MERGE komutu aşağıdaki gibi görünür;

MERGE <target_table> [AS TARGET]
USING <table_source> [AS SOURCE]
ON <search_condition>
[WHEN MATCHED 
   THEN <merge_matched> ]
[WHEN NOT MATCHED [BY TARGET]
   THEN <merge_not_matched> ]
[WHEN NOT MATCHED BY SOURCE
   THEN <merge_matched> ];

Merge komutunu kullanmak için Hedef ve Kaynak tablolarınız belirlemiş olmanız gerekmekte. Satırları eşitlemek için Hedef ve Kaynak eşitliğini ON ifadesinden sonra sağlamanız gerekmektedir.

Kayıtlar Hedef ve Kaynak, yani karşılaştırma koşulları arasında eşleştirilip eşleştirilmediği mantığını belirtin.

Karşılaştırma koşullarının her biri için kodlama yapın.Eşleşme sağlandığında UPDATE işlemi kullanılır. Eşleşmediğinde bir INSERT veya DELETE işlemi kullanılır.

 

Şimdi örneğimiz için Demo tablolarımızı oluşturup datalarımızı basıyor olacağız.

--Hedef tablomuzu olusturuyoruz.
CREATE TABLE Product_Target
(
   ProductID INT PRIMARY KEY,
   ProductName VARCHAR(100),
   Rate MONEY
) 
GO

Yukarıda Target yani Hedef tablomuzu oluşturduk. Şimdi bu tablomuza data basalım.

INSERT INTO Product_Target
VALUES
   (1, 'Tea', 10.00),
   (2, 'Coffee', 20.00),
   (3, 'Muffin', 30.00),
   (4, 'Biscuit', 40.00)
GO

Target demo tablomuzu bitirdikten sonra Source yani kaynak tablomuzu oluşturacağız.

CREATE TABLE Product_Source
(
   ProductID INT PRIMARY KEY,
   ProductName VARCHAR(100),
   Rate MONEY
) 
GO

Source tablomuza da demo datalarımızı basalım.

INSERT INTO Product_Source
VALUES
   (1, 'Tea', 10.00),
   (2, 'Coffee', 25.00),
   (3, 'Muffin', 35.00),
   (5, 'Pizza', 60.00)
GO

Şimdi ise her işki tabloya da SELECT çekerek kontrol işlemimizi sağlayalım.

SELECT * FROM Product_Target
SELECT * FROM Product_Source
GO

Ardından, hedef tabloyu kaynak tablodan gelen yenilenmiş verilerle senkronize etmek için MERGE komutunu kullanacağım.

Şimdi ise geniş bir MERGE işlemini yapacak scripti yazacağız. Çünkü gördüğünüz üzere Kaynak tabloda hem Rate ler değişmiş hem de Ürün eklenmiş vb. süreçler yer almakta. Tek bir işlemle tüm kaynak değerlerini hedef e aktaracak scriptimizi Merge deyimi kullanarak sağlayacağız.

Kısaca biz şunu demiş olacağız scriptimiz ile Hedef tabloyu kaynak tablodan yenilenen verilerle senkronize et.

MERGE Product_Target AS TARGET
USING Product_Source AS SOURCE 
ON (TARGET.ProductID = SOURCE.ProductID) 
--- Kayıtlar eşleştiğinde, herhangi bir değişiklik varsa kayıtları güncelleyin
WHEN MATCHED AND TARGET.ProductName <> SOURCE.ProductName OR TARGET.Rate <> SOURCE.Rate 
THEN UPDATE SET TARGET.ProductName = SOURCE.ProductName, TARGET.Rate = SOURCE.Rate 
--- Hiçbir kayıt eşleşmediğinde, gelen kayıtları kaynak tablodan hedef tabloya ekleyin
WHEN NOT MATCHED BY TARGET 
THEN INSERT (ProductID, ProductName, Rate) VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Rate)
--Hedefte bir satır olduğunda ve kaynakta aynı kayıt bulunmadığında bu kayıt hedefini silin
WHEN NOT MATCHED BY SOURCE 
THEN DELETE 
--$ action, OUTPUT yan tümcesinde döndüren nvarchar (10) türünde bir sütun belirtir.
--her satır için üç değerden biri: o satırda gerçekleştirilen eyleme göre 'INSERT', 'UPDATE' veya 'DELETE'
OUTPUT $action, 
DELETED.ProductID AS TargetProductID, 
DELETED.ProductName AS TargetProductName, 
DELETED.Rate AS TargetRate, 
INSERTED.ProductID AS SourceProductID, 
INSERTED.ProductName AS SourceProductName, 
INSERTED.Rate AS SourceRate; 

SELECT @@ROWCOUNT;
GO

Sonuç :

Merge işlemi bittikten sonra hem Target hemde Source tablomuza SELECt çekelim ve her iki tablonunda eşit olmasını beklemekteyiz.

SELECT * FROM Product_Target
SELECT * FROM Product_Source
GO

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *