Zaktualizuj wszystkie kolumny z innej tabeli

13

Muszę zaktualizować tabelę z innej i muszę zaktualizować wszystkie kolumny. Czy oprócz listy wszystkich kolumn w SETklauzuli istnieje sposób na ich zaktualizowanie naraz? Lubię to:

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

Próbowałem w psql, to nie działa. Muszę wymienić każdą kolumnę w następujący sposób:

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

tableBjest stworzony use create .. like tableA. Są w zasadzie identyczne. Powodem, dla którego to robię, jest konieczność załadowania danych .csv do tabeli tymczasowej, tableBa następnie aktualizacji w tableAoparciu o nowe dane tableB. tableAmusi być jak najmniej zamknięty i tableAmusi zachowywać integralność. Nie jestem pewien, czy dobrym pomysłem byłoby „usuń, a następnie wstaw”?

odieatla
źródło
1
Przetestowałem twój drugi kod, działa! Powinieneś przejrzeć dwa tematy: dba.stackexchange.com/questions/58371/... , dba.stackexchange.com/questions/59458/...
Luan Huynh

Odpowiedzi:

12

Nie ma wariantu składni, który pozwala aktualizować cały wiersz na raz. Istnieje jednak krótsza forma niż dotychczas.

Nie chcesz też aktualizować wszystkich kolumn. WHEREStan sworzni id dół co najmniej jedną kolumnę ( id), pozostały niezmienione. Ale to tylko drapanie.

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

Więcej szczegółów w tej pokrewnej odpowiedzi:
Zbiorcza aktualizacja wszystkich kolumn

DELETE / INSERT

Wewnętrznie, dzięki modelowi Postgres MVCC , każdy i tak UPDATEskutecznie wstawia nowy wiersz i oznacza stary jako przestarzały. Tak więc za zasłonami nie ma dużej różnicy między plus UPDATEa . Istnieje kilka szczegółów na korzyść trasy: DELETEINSERT
UPDATE

  • GORĄCA AKTUALIZACJA.
  • Tabele TOAST: Jeśli masz duże kolumny, zawartość może być przechowywana. „Poza linią” w tabelach TOAST, a nowa wersja wiersza może prowadzić do tego samego wiersza w tabeli TOAST, jeśli tosty kolumny pozostaną niezmienione.
  • Utrzymanie indeksu może być tańsze w przypadku aktualizacji.

W przeciwnym razie blokowanie powinno być mniej więcej takie samo. Tak czy inaczej, potrzebujesz wyłącznej blokady w dotkniętych rzędach. Po prostu zrób to szybko.
Jeśli masz do czynienia z dużą liczbą wierszy i nie potrzebujesz spójnego stanu (wszystkie wiersze lub żaden), możesz podzielić operację na wiele partii. (Oddzielne transakcje!) Zwiększa całkowity koszt, ale skraca czas blokady na wiersz.

Erwin Brandstetter
źródło
3
DELETE / INSERTmogą również mieć niepożądane lub po prostu inne (kaskadowe lub wywołane) efekty niż UPDATE.
ypercubeᵀᴹ
Jest to poprawne, ale powinieneś zaktualizować alias część table_a. table_a (która jest zaktualizowaną tabelą) nie może uzyskać aliasu.
Just Another Code Lover