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

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должен сохранять целостность. Я не уверен, что «удалить, а затем вставить» будет хорошим вариантом?

odieatla
источник
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 (который является обновленной таблицей) не может получить псевдоним.
Просто еще один любитель кода