Muszę zaktualizować tabelę z innej i muszę zaktualizować wszystkie kolumny. Czy oprócz listy wszystkich kolumn w SET
klauzuli 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
tableB
jest stworzony use create .. like tableA
. Są w zasadzie identyczne. Powodem, dla którego to robię, jest konieczność załadowania danych .csv do tabeli tymczasowej, tableB
a następnie aktualizacji w tableA
oparciu o nowe dane tableB
. tableA
musi być jak najmniej zamknięty i tableA
musi zachowywać integralność. Nie jestem pewien, czy dobrym pomysłem byłoby „usuń, a następnie wstaw”?
postgresql
update
odieatla
źródło
źródło
Odpowiedzi:
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.
WHERE
Stan sworzni id dół co najmniej jedną kolumnę (id
), pozostały niezmienione. Ale to tylko drapanie.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
UPDATE
skutecznie wstawia nowy wiersz i oznacza stary jako przestarzały. Tak więc za zasłonami nie ma dużej różnicy między plusUPDATE
a . Istnieje kilka szczegółów na korzyść trasy:DELETE
INSERT
UPDATE
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.
źródło
DELETE / INSERT
mogą również mieć niepożądane lub po prostu inne (kaskadowe lub wywołane) efekty niżUPDATE
.