Обновить все столбцы из другой таблицы


13

Мне нужно обновить таблицу из другой, и мне нужно обновить все столбцы. Помимо перечисления каждого столбца в SETпредложении, есть ли способ обновить их все сразу? Как это:

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

Я пытался в PSQL, это не работает. Я должен перечислить каждый столбец следующим образом:

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

tableBсоздан для использования create .. like tableA. Так что они в основном идентичны. И причина, по которой я это делаю, заключается в том, что мне нужно загрузить данные .csv во временную таблицу, tableBа затем обновить их tableAна основе новых данных tableB. tableAдолжен быть как можно меньше заблокирован и tableAдолжен сохранять целостность. Я не уверен, что «удалить, а затем вставить» будет хорошим вариантом?


1
Я проверил с вашим вторым кодом, это работает! Вам следует ознакомиться с двумя темами: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Луан

Ответы:


12

Не существует синтаксического варианта, который позволял бы обновлять всю строку сразу. Тем не менее, есть более короткая форма, чем у вас до сих пор.

Кроме того, вы не хотите обновлять все столбцы. WHEREУсловие на Ид штифтах вниз по меньшей мере , одного столбца ( id) остается неизменным. Но это просто придирки.

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

Подробнее в этом связанном ответе:
Массовое обновление всех столбцов

DELETE / INSERT

Внутренне, благодаря модели Postgres MVCC , каждый UPDATEэффективно вставляет новый ряд в любом случае и помечает старый как устаревший. Так что за занавесками нет большой разницы между плюсом UPDATEи DELETEплюсом INSERT.
Есть некоторые подробности в пользу UPDATEмаршрута:

  • ГОРЯЧЕЕ ОБНОВЛЕНИЕ.
  • Таблицы TOAST: Если у вас большие столбцы, содержимое может храниться вне таблицы в таблицах TOAST, и новая версия строки может ссылаться на ту же строку в таблице TOAST, если поднятые столбцы остаются неизменными.
  • Обслуживание индекса может быть дешевле для обновлений.

В противном случае блокировка должна быть примерно такой же. В любом случае вам нужна эксклюзивная блокировка для затронутых рядов. Просто сделай это быстро.
Если вы имеете дело с огромным количеством строк и вам не нужно согласованное состояние (все строки или ни одного), вы можете разделить операцию на несколько пакетов. (Отдельные транзакции!) Увеличивает общую стоимость, но сокращает время блокировки на строку.


3
DELETE / INSERTможет также иметь нежелательные или просто другие (каскадные или сработавшие) эффекты, чем UPDATE.
ypercubeᵀᴹ

Это правильно, но вы должны обновить алиасную часть table_a. table_a (который является обновленной таблицей) не может получить псевдоним.
Просто еще один любитель кода
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.