PostgreSQL ÇATIŞMA GÜNCELLEMESİNE EKLE (upert) hariç tutulan tüm değerleri kullanır


142

Bir satırı yükseltirken (PostgreSQL> = 9.5) ve olası INSERT'in olası UPDATE ile tam olarak aynı olmasını istiyorsanız, bunu şu şekilde yazabilirsiniz:

INSERT INTO tablename (id, username, password, level, email) 
                VALUES (1, 'John', 'qwerty', 5, 'john@mail.com') 
ON CONFLICT (id) DO UPDATE SET 
  id=EXCLUDED.id, username=EXCLUDED.username,
  password=EXCLUDED.password, level=EXCLUDED.level,email=EXCLUDED.email

Daha kısa bir yol var mı? Sadece söylemek gerekirse: tüm EXCLUDE değerlerini kullanın.

SQLite yaptım:

INSERT OR REPLACE INTO tablename (id, user, password, level, email) 
                        VALUES (1, 'John', 'qwerty', 5, 'john@mail.com')

43
Gerçek bir cevap değil ama kısa bir süre gösterim kullanabilirsiniz: INSERT INTO tablename (id, username, password, level, email) VALUES (1, 'John', 'qwerty', 5, 'john@mail.com') ON CONFLICT (id) DO UPDATE SET (username, password, level, email) = (EXCLUDED.username, EXCLUDED.password, EXCLUDED.level, EXCLUDED.email).Neredeyse aynı, ancak sütun listesini kopyalamak / yapıştırmak / yönetmek kolaydır
tay

Başka bir seçenek jsonb sütunlarını kullanmaktır ve bu şekilde sütunlar için endişelenmenize gerek yoktur
j

Yanıtlar:


162

Postgres ile eşdeğer bir uygulama yapmadı INSERT OR REPLACE. Gönderen ON CONFLICTdocs (vurgu benim):

Bir çakışma durumunda gerçekleştirilecek UPDATE eyleminin ayrıntılarını belirten DO NOTHING veya DO UPDATE yan tümcesi olabilir.

Size değiştirme için kısayol vermese de ON CONFLICT DO UPDATE, önceden var olan verilere göre yeni değerler ayarlamanıza izin verdiği için daha genel olarak geçerlidir. Örneğin:

INSERT INTO users (id, level)
VALUES (1, 0)
ON CONFLICT (id) DO UPDATE
SET level = users.level + 1;

3
Dikkat edilmesi gereken bir nokta olarak, "güncellemede" genellikle aynı yerde kullanılabilmesine rağmen SQL standardının "birleştirilmesi" ile anlamsal olarak aynı değildir. "Çakışma güncellemesi" nin başlamasını beklediğim bir durum vardı, ancak ekteki kesin sorun güncellemenin (bu hasarlı kaydı onardı) tetiklemedi.
pojo-guy

2
"Ancak ekteki kesin sorun güncellemeye neden olmadı" yı genişletebilir misiniz?
18'de MrR

@ pojo-guy - MrR'nin sorusunu gördüğünüzü sanmıyorum - Genişleyebilir misiniz? "ancak ekteki kesin sorun güncellemeye neden olmadı?"
Randall

Postgresql dosyasındaki güncellemede insert ... komutunu kullanmaya çalıştığınızda, sonuçlar bazı özel durumlarda birleştirme işleminden farklıdır. Karşılaştığım dava oldukça belirsiz ve spesifikti, ancak tekrarlanabilirdi. Birkaç ay oldu, bu yüzden daha fazla hak veremem.
pojo-guy

Belki de bir çakışma değil, başka bir hata, örneğin alan tipi hatası?
19R
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.