Banyak orang akan menyarankan Anda menggunakan MERGE
, tapi saya memperingatkan Anda untuk tidak melakukannya. Secara default, ini tidak melindungi Anda dari concurrency dan kondisi balapan lebih dari beberapa pernyataan, tetapi itu menimbulkan bahaya lain:
- Berhati-hatilah dengan Pernyataan MERGE SQL Server
- Yang Harus Dihindari Jika Anda Ingin Menggunakan MERGE
- Pola dan Antipattern UPSERT SQL Server
Bahkan dengan sintaks "lebih sederhana" ini tersedia, saya masih lebih suka pendekatan ini (penanganan kesalahan dihilangkan untuk singkatnya):
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;
Info lebih lanjut tentang UPSERT
ini pendekatan di sini:
- Harap berhenti menggunakan anti-pola UPSERT ini
Banyak orang akan menyarankan cara ini:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
UPDATE ...
END
ELSE
BEGIN
INSERT ...
END
COMMIT TRANSACTION;
Tetapi semua yang dicapai adalah memastikan Anda mungkin perlu membaca tabel dua kali untuk menemukan baris yang akan diperbarui. Dalam contoh pertama, Anda hanya perlu mencari baris sekali. (Dalam kedua kasus, jika tidak ada baris yang ditemukan dari pembacaan awal, penyisipan terjadi.)
Orang lain akan menyarankan cara ini:
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 2627
UPDATE ...
END CATCH
Namun, ini bermasalah jika tidak ada alasan lain selain membiarkan SQL Server menangkap pengecualian yang bisa Anda cegah sejak awal jauh lebih mahal, kecuali dalam skenario langka di mana hampir setiap penyisipan gagal. Saya buktikan disini:
- Memeriksa potensi pelanggaran batasan sebelum memasuki TRY/CATCH
- Dampak kinerja dari berbagai teknik penanganan kesalahan
Tidak yakin apa yang Anda pikir Anda peroleh dengan memiliki satu pernyataan; Saya tidak berpikir Anda mendapatkan apa-apa. MERGE
adalah pernyataan tunggal tetapi tetap harus benar-benar melakukan beberapa operasi - meskipun itu membuat Anda berpikir tidak.