Perbarui semua kolom dari tabel lain

13

Saya perlu memperbarui tabel dari yang lain, dan saya perlu memperbarui semua kolom. Selain mencantumkan setiap kolom dalam SETklausa, apakah ada cara untuk memperbarui semuanya sekaligus? Seperti ini:

update tableA
set * = tableB.*
from tableB where tableA.id = tableB.id

Saya mencoba psql, tidak berhasil. Saya harus mendaftar setiap kolom seperti ini:

update tableA
set c1 = tableB.c1, c2 = tableB.c2, ...
from tableB where tableA.id = tableB.id

tableBdibuat digunakan create .. like tableA. Jadi mereka pada dasarnya identik. Dan alasan saya melakukannya adalah karena saya perlu memuat data .csv ke tabel temp tableBdan kemudian memperbarui tableAberdasarkan data baru di tableB. tableAperlu dikunci sesedikit mungkin dan tableAperlu menjaga integritas. Saya tidak yakin 'hapus lalu masukkan' akan menjadi opsi yang baik?

odieatla
sumber
1
Saya menguji dengan kode kedua Anda, itu berhasil! Anda harus meninjau dua topik: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Luan Huynh

Jawaban:

12

Ada ada varian sintaks yang memungkinkan Anda memperbarui seluruh baris sekaligus. Namun, ada bentuk yang lebih pendek dari yang Anda miliki sejauh ini.

Selain itu, Anda sebenarnya tidak ingin memperbarui semua kolom. The WHEREkondisi pada pin id turun setidaknya satu kolom (id ) tetap tidak berubah. Tapi itu hanya nitpicking.

UPDATE table_a a
SET    (  c1,   c2, ...)
     = (b.c1, b.c2, ...)
FROM   table_b b
WHERE  a.id = b.id;

Lebih detail dalam jawaban terkait ini:
Pembaruan massal semua kolom

DELETE / INSERT

Secara internal, karena model MVCC Postgres , bagaimanapun juga setiap UPDATEbaris secara efektif menyisipkan baris baru dan menandai yang lama sebagai usang. Jadi, di balik gorden tidak ada banyak perbedaan antara UPDATEdan DELETEplus INSERT.
Ada beberapa detail yang mendukungUPDATE rute:

  • PEMBARUAN PANAS.
  • Tabel TOAST: Jika Anda memiliki kolom besar, konten dapat disimpan. "Out-of-line" di tabel TOAST dan versi baris baru dapat menautkan ke baris yang sama dalam tabel TOAST jika kolom panggang tetap tidak berubah.
  • Pemeliharaan indeks mungkin lebih murah untuk pembaruan.

Kalau tidak, pengunciannya harus hampir sama. Anda memerlukan kunci eksklusif pada baris yang terpengaruh. Cepat saja.
Jika Anda berurusan dengan sejumlah besar baris dan Anda tidak memerlukan status yang konsisten (semua baris atau tidak sama sekali), Anda dapat membagi operasi menjadi beberapa batch. (Transaksi terpisah!) Meningkatkan total biaya, tetapi mempersingkat waktu penguncian per baris.

Erwin Brandstetter
sumber
3
DELETE / INSERTmungkin juga memiliki efek yang tidak diinginkan atau hanya berbeda (kaskade atau dipicu) dari UPDATE.
ypercubeᵀᴹ
Itu benar tetapi Anda harus memperbarui alias bagian dari table_a. table_a (yang diperbarui tabel) tidak bisa mendapatkan alias.
Just Another Code Lover