Actualizar todas las columnas de otra tabla

13

Necesito actualizar una tabla de otra, y necesito actualizar todas las columnas. Además de enumerar todas las columnas de la SETcláusula, ¿hay alguna forma de actualizarlas todas a la vez? Me gusta esto:

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

Lo intenté en psql, no funciona. Tengo que enumerar cada columna de esta manera:

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

tableBSe crea uso create .. like tableA. Entonces son básicamente idénticos. Y la razón por la que lo hago es que necesito cargar datos .csv en una tabla temporal tableBy luego actualizarlos en tableAfunción de los nuevos datos tableB. tableAnecesita ser bloqueado lo menos posible y tableAdebe mantener la integridad. No estoy seguro de que 'eliminar y luego insertar' sea una buena opción.

odieatla
fuente
1
Lo probé con tu segundo código, ¡funciona! Debe revisar dos temas: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Luan Huynh

Respuestas:

12

No hay variante de sintaxis que le permita actualizar toda la fila a la vez. Sin embargo, hay una forma más corta que la que tienes hasta ahora.

Además, en realidad no desea actualizar todas las columnas. La WHEREcondición en la identificación fija al menos una columna ( id) para permanecer sin cambios. Pero eso es solo una trampa.

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

Más detalles en esta respuesta relacionada:
actualización masiva de todas las columnas

DELETE / INSERT

Internamente, debido al modelo MVCC de Postgres , cada uno UPDATEinserta efectivamente una nueva fila y marca la antigua como obsoleta. Entonces, detrás de las cortinas no hay mucha diferencia entre UPDATEy DELETEmás INSERT.
Hay algunos detalles a favor de la UPDATEruta:

  • ACTUALIZACIÓN CALIENTE.
  • Tablas TOAST: si tiene columnas grandes, el contenido puede almacenarse "fuera de línea" en las tablas TOAST y la nueva versión de la fila puede vincularse a la misma fila en la tabla TOAST si las columnas tostadas permanecen sin cambios.
  • El mantenimiento del índice puede ser más barato para las actualizaciones.

De lo contrario, el bloqueo debería ser casi igual. Necesita un bloqueo exclusivo en las filas afectadas de cualquier manera. Solo hazlo rápido.
Si está tratando con una gran cantidad de filas y no necesita un estado consistente (todas las filas o ninguna), puede dividir la operación en varios lotes. (¡Transacciones separadas!) Aumenta el costo total, pero mantiene el tiempo de bloqueo por fila más corto.

Erwin Brandstetter
fuente
3
DELETE / INSERTtambién puede tener efectos no deseados o simplemente diferentes (en cascada o disparados) que el UPDATE.
ypercubeᵀᴹ
Es correcto, pero debe actualizar parte del alias de table_a. table_a (que es una tabla actualizada) no puede obtener un alias.
Just Another Code Lover