UPSERT - MERGE veya @@ rowcount'a daha iyi bir alternatif var mı? [kapalı]


14

UPSERT kavramına benzer bir T-SQL komutuyla karşılaşıp karşılaşmadığınızı merak ediyordum. (1) veya (2) seçeneklerini kullanarak INSERT | UPDATE işlemlerini gerçekleştirmek aşırı karmaşık ve hataya açık görünüyor.

AMAÇ

İstenen kaydın (bu durumda çalışan_kimliği 1) güncel olduğundan emin olmak için, aynı sorguyu esasen iki kez yazmak zorunda kalmadan.

BAĞLAM

  • tablo adı: çalışan
  • çalışan kimliği: birincil bir anahtarı var ve kimlik özelliği doğru olarak ayarlanmış

SEÇENEKLER

  1. SQL UPDATE yürütme ... check @@ rowcount = 0 ve @@ error = 0 ... gerekirse SQL INSERT yürütme

    • con: Aynı sorguyu, biri ek olarak, bir kez güncelleme olarak iki kez etkili bir şekilde yazmanız gerekir
    • con: daha fazla kod = daha fazla zaman yazmak
    • con: daha fazla kod = hata için daha fazla alan

/programming/1106717/how-to-implement-a-conditional-upsert-stored-procedure "@@ rowcount kullanarak güncelleme"

  1. SQL MERGE yürütme
    • con: Aynı sorguyu, biri ek olarak, bir kez güncelleme olarak iki kez etkili bir şekilde yazmanız gerekir
    • con: daha fazla kod = daha fazla zaman yazmak
    • con: daha fazla kod = hata için daha fazla alan

http://technet.microsoft.com/tr-tr/library/bb510625.aspx "T-SQL Birleştirme"

  1. SQL UPSERT yürütme (özellik mevcut değil)
    • pro: veri-tablo ilişkisini bir kez tanımlarsınız (SQL Server'ın bir INSERT veya UPDATE olup olmadığı konusunda endişelenmesine izin verin)
    • pro: daha az kod = daha hızlı uygulama
    • pro: daha az kod = daha düşük olasılık

UPSERT ÖRNEĞİ

UPSERT çalışanı (çalışan_kimliği, çalışan_sayısı, iş_başlığı, ad_adı, orta_adı, soyadı, değiştirilmiş_at) DEĞERLER (1, '00 -124AB37 ',' Yönetici ',' John ',' T ',' Smith ', GetDate ());

  • çalışan_kimliği 1 yoksa: MS SQL bir INSERT deyimi yürütür
  • çalışan_kimliği 1 varsa: MS SQL yürütülür ve UPDATE deyimi

4
Bu, Microsoft için bir özellik isteği gibi görünüyor, burada kimsenin çözmenize yardımcı olabileceği bir şey değil. Microsoft'un getirdiği çözüm MERGE. Bu sizin için yeterince esnek / güçlü değilse, henüz var olmayan farklı bir çözüme ihtiyacınız var.
Aaron Bertrand

3
Kanımca, MERGEbasit, esnek ve aynı zamanda SQL Standardının bir parçasıdır. Gerçek sorun MERGEve diğer UPSERTuygulamalar, sözdizimi ile hiçbir ilgisi olmayan potansiyel kilit yükseltme ve hatta çıkmazlardır.
a1ex07

Bir sorunuz varsa, sormaktan çekinmeyin. Yazıldığı gibi bu temelde MERGESQL Server'da uygulama hakkında bir diatribe .
JNK

İyi soru - aslında sunucunun bir ekleme veya güncelleme gerektirdiğinden endişe ettiği bir UPSERT ifadesi var. Katılıyorum, MERGE "UPSERT" uygulamasından mantıklı bir şekilde beklediğinizi karşılamıyor. MS'in bu şekilde uygulamayı seçmesi durumunda, sorum şu olurdu: sizin (ve ben) istediğiniz sözdizimini uygulamaya çalışmış olsalardı, bir eksiklik veya uygulanması imkansız olabilirdi?
youcantryreachingme

Yanıtlar:


14

Bence bunun basit cevabı hayır. MERGEMicrosoft'un daha kıvrımlı UPSERTmantığa cevabı oldu . Ve en kötü yaklaşımı bile listelemediniz:

IF (SELECT COUNT ... ) > 0
    UPDATE
ELSE
    INSERT

Biraz yazarak ağzıma attım, ama aslında en sık gördüğüm şey.

Her durumda, MERGEsizin için yeterince esnek veya güçlü değilse, http://connect.microsoft.com/sql/ adresinden Microsoft'a bir özellik isteği göndermenizi ve iş durumunuzu ayrıntılı bir şekilde açıklamanızı öneririm . Önerdiğiniz sözdiziminin gerçek avantajlarına sadık kaldığınız sürece MERGEoyumu alırsınız. "Hataya meyilli" kısımda çok fazla asılı kalırsanız, içeri girme ihtimalim yüksek değil. Neden? Çünkü herhangi bir ifadeyi yağlayabilirsiniz.

Bununla birlikte, burada kimsenin sizin için özel olarak yapabileceği bir şey olduğunu sanmıyorum. Aşağıdakilerle ilgili olası sorunları araştırmalısınız MERGE:

http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/


2
Teşekkürler Aaron. MSDN'de T-SQL belgelerine baktım ve aradığım şeyi bulamadım; sadece bir şeyleri kaçırırsam dışarı fırlatacağımı düşündüm. MERGE ifadesi belirli durumlarda mantıklı olsa da, basit bir kaydetme işlemi için "çiviye vurmak için bir kızak çekiç" çözümü olduğunu hissetmiyorum. Belki de programcı şapkamı almalı ve DBA Fedora'mı takmalıyım. Düşüncelerinizi paylaşmak için zaman ayırdığınız için teşekkür ederiz.
Pressacco
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.