Оновіть усі стовпці з іншої таблиці


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/…
Luan Huynh

Відповіді:


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

Внутрішньо, завдяки моделі MVCC Postgres , кожен 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.