web-dev-qa-db-fra.com

Mettre à jour toutes les colonnes d'une autre table

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 clause SET, existe-t-il un moyen de les mettre à jour en même temps? 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

tableB est créé à l'aide de 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 tableA en fonction des nouvelles données dans tableB. tableA doit être verrouillé le moins possible et tableA doit conserver son intégrité. Je ne suis pas sûr que "supprimer puis insérer" serait une bonne option?

13
odieatla

Il n'y a pas de 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 condition WHERE sur les repères d'identification vers le bas sur 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 UPDATE insère de toute façon 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 UPDATE et DELETE plus INSERT.
Il y a quelques détails en faveur de la route UPDATE:

  • HOT UPDATE.
  • 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.

12
Erwin Brandstetter