Tekli sorgu kullanarak nasıl eklenir veya güncellenir?


25

Birincil anahtarın ve otomatik artışın ve adın verildiği sütun kimliğine sahip bir tablo testim var. Yeni bir kayıt eklemek istiyorum, eğer sadece kayıt yoksa yenile.

giriş id = 30122 ve name = john

30122 kimliğine sahip kayıtlar varsa, o zaman isim sütununu john olarak güncellerim, eğer kayıt yoksa o zaman yeni bir kayıt eklerim.

Gibi 2 sorgu kullanarak yapabilirim

select * from test where id=30122

bazı kayıtları varsa o zaman kullanabilirim update test set name='john' where id=3012

veya eğer kayıtları yoksa o zaman kullanabilirim

insert into test(name) values('john')

Ancak tek sorgu kullanmak istedim?

Birisi mümkün olup olmadığını söyleyebilir mi?


1
But I wanted to use single query?Niye ya?
Aaron Bertrand

@AaronBertrand Arka uç java kullanılarak geliştirildi.So 2 çeyrek kullanırsam, o zaman DB 2 kere çarpmak zorundayım. Tek bir sorgu kullanarak yapılabiliyorsa neden 2 sorgu kullanmalı
SpringLearner

1
Java, veritabanına yalnızca bir isabet gerektiren iki ifadeli tek bir toplu işlemi veya saklı bir işlemi desteklemiyor mu?
Aaron Bertrand

@AaronBertrand, bunu sql server 2008 ya da üstü ile nasıl idare edeceğinize bir örnek verebilir misiniz?
eaglei22

1
@ eaglei22 Aşağıdaki örneği vijayp'in cevabındaki 2. örneği kullanırdım. Hala seçim olmaz MERGEhatta SQL Server 2019, herhangi bir sürümünde burada bu konuda bazı arka plan .
Aaron Bertrand

Yanıtlar:


41

Bunu deneyebilirsin

IF EXISTS(select * from test where id=30122)
   update test set name='john' where id=3012
ELSE
   insert into test(name) values('john');

Daha iyi performans için diğer yaklaşım

update test set name='john' where id=3012
IF @@ROWCOUNT=0
   insert into test(name) values('john');

ve ayrıca şema öneki üzerinde tekme bu kötü alışkanlıkları okuyun


4
İlk örnek boşa harcanır ve sık sık kilitlenmelere yol açabilir - bunu kesinlikle önermem.
Aaron Bertrand

@AaronBertrand detaylandırmak ister misiniz? Teşekkürler
Hexo,

5
@SlapY Tabii ki, ilk örnekte, şöyle diyorsunuz: "Hey, SQL Server, bu kimliğe sahip bir satır var mı?" SQL Server, belki de bir tarama kullanarak satırı bulmak için kapanır ve ardından yanıtla geri döner. “Neden, evet, kullanıcı, bu kimliğe sahip bir satırım var!” Sonra "Tamam, SQL Server, git o satırı tekrar bul , ama bu sefer güncelle!" Diyorsun. Arama veya taramanın iki kez gerçekleştirilmesinin boşa gittiğini görüyor musunuz? Başka bir kullanıcı SQL Server'a bir satırın varlığına ilişkin aynı soruyu sorarsa, bunun hakkında bir şeyler yapmaya başlamadan önce ne olacağını hayal edebiliyor musunuz?
Aaron Bertrand

Teşekkürler, sadece ilk değil neden ikincinin kilitlenme tehdidi olduğunu anlamıyorum? Her ikisi de tam kilitle çalıştırılmazsa yakalanabilecek çok sayıda ifadeden oluşur. Yanlış mıyım?
Hexo

2
@ 0x25b3 Biri kilitlenmeler tarafından tehdit edilmiyor, diğeri de değil, ilk örneğin onlara daha eğilimli olduğu. Her iki durumda da tam ve doğru bir işlem yapmalısınız, ancak insanlar bunu yapmazlar, yani ...
Aaron Bertrand

17

SQL Server 2008 veya sonraki bir sürüm varsayarak, şunları kullanabilirsiniz MERGE:

tablo

CREATE TABLE dbo.Test
(
    id integer NOT NULL,
    name varchar(30) NULL,

    CONSTRAINT PK_dbo_Test__id
        PRIMARY KEY CLUSTERED (id)
);

Sorgu

MERGE dbo.Test WITH (SERIALIZABLE) AS T
USING (VALUES (3012, 'john')) AS U (id, name)
    ON U.id = T.id
WHEN MATCHED THEN 
    UPDATE SET T.name = U.name
WHEN NOT MATCHED THEN
    INSERT (id, name) 
    VALUES (U.id, U.name);

SERIALIZABLEİpucu için gerekli olan yüksek eşzamanlılık altında doğru işlem .

Michael J. Swart tarafından ortak yöntemlerin bir karşılaştırmasını burada bulabilirsiniz:

Efsane: Eşzamanlı Güncelleme / Ekleme Çözümleri


8
Birleşmenin bazı sorunları var .
von

orada efsanevi bağlantı mükemmel. Güzel bir!
JonnyRaa
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.