Mettre à jour toutes les colonnes d'une autre table

13

J'ai besoin de mettre à jour une table à partir d'une autre et j'ai besoin de mettre à jour toutes les colonnes. Outre la liste de toutes les colonnes de la SETclause, existe-t-il un moyen de les mettre à jour simultanément? Comme ça:

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

J'ai essayé en psql, ça ne marche pas. Je dois lister chaque colonne comme ceci:

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

tableBest créé utiliser create .. like tableA. Ils sont donc fondamentalement identiques. Et la raison pour laquelle je le fais est que je dois charger des données .csv dans une table temporaire tableB, puis mettre à jour en tableAfonction des nouvelles données dans tableB. tableAdoit être verrouillé le moins possible et tableAdoit conserver son intégrité. Je ne suis pas sûr que «supprimer puis insérer» serait une bonne option?

odieatla
la source
1
J'ai testé avec votre second code, ça marche! Vous devriez revoir deux sujets: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Luan Huynh

Réponses:

12

Il n'y a aucune variante de syntaxe qui vous permet de mettre à jour la ligne entière à la fois. Cependant, il existe une forme plus courte que celle que vous avez jusqu'à présent.

En outre, vous ne souhaitez pas réellement mettre à jour toutes les colonnes. La WHEREcondition sur l'ID épingle au moins une colonne ( id) pour rester inchangée. Mais c'est juste une piqûre.

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

Plus de détails dans cette réponse connexe:
mise à jour en masse de toutes les colonnes

DELETE / INSERT

En interne, en raison du modèle MVCC de Postgres , chaque UPDATEinsère effectivement une nouvelle ligne et marque l'ancienne comme obsolète. Donc, derrière les rideaux, il n'y a pas beaucoup de différence entre UPDATEet DELETEplus INSERT.
Il y a quelques détails en faveur de l' UPDATEitinéraire:

  • MISE À JOUR À CHAUD.
  • Tables TOAST: Si vous avez de grandes colonnes, le contenu peut être stocké. "Hors ligne" dans les tables TOAST et la nouvelle version de ligne peut être liée à la même ligne dans la table TOAST si les colonnes grillées restent inchangées.
  • La maintenance de l'index peut être moins chère pour les mises à jour.

Sinon, le verrouillage devrait être à peu près le même. Vous avez besoin d'un verrou exclusif sur les lignes affectées dans les deux cas. Faites vite.
Si vous traitez un grand nombre de lignes et que vous n'avez pas besoin d'un état cohérent (toutes les lignes ou aucune), vous pouvez diviser l'opération en plusieurs lots. (Transactions séparées!) Augmente le coût total, mais réduit le temps de verrouillage par ligne.

Erwin Brandstetter
la source
3
DELETE / INSERTpeut également avoir des effets indésirables ou simplement différents (en cascade ou déclenchés) que UPDATE.
ypercubeᵀᴹ
C'est correct mais vous devez mettre à jour la partie alias de table_a. table_a (qui est une table mise à jour) ne peut pas obtenir d'alias.
Just Another Code Lover