Birçok kişi kullanmanızı önerir MERGE
, ama ben buna karşı uyarıyorum. Varsayılan olarak, sizi birden fazla ifadeden daha fazla eşzamanlılık ve yarış koşullarından korumaz ve diğer tehlikeleri ortaya çıkarır:
http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
Bu "daha basit" sözdizimi ile bile, hala bu yaklaşımı tercih ediyorum (kısalık için hata işleme atlandı):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;
Birçok kişi şu şekilde önerecektir:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
UPDATE ...
END
ELSE
INSERT ...
END
COMMIT TRANSACTION;
Ancak tüm bunlar, güncellenecek satır (lar) ı bulmak için tabloyu iki kez okumanız gerekebileceğinden emin olmaktır. İlk örnekte, satır (lar) ı yalnızca bir kez bulmanız gerekecektir. (Her iki durumda da, ilk okumada hiç satır bulunmazsa, bir ekleme yapılır.)
Diğerleri şöyle önerecektir:
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 2627
UPDATE ...
END CATCH
Ancak, SQL Server'ın ilk etapta önleyebileceğiniz istisnaları yakalamasına izin vermekten başka bir sebep yoksa, neredeyse her ekin başarısız olduğu nadir senaryo dışında çok daha pahalıysa bu sorunludur. Burada kanıtladığım kadarıyla: