Aggiorna tutte le colonne da un'altra tabella


13

Devo aggiornare una tabella da un'altra e ho bisogno di aggiornare tutte le colonne. Oltre a elencare ogni colonna nella SETclausola, c'è un modo per aggiornarle tutte in una volta? Come questo:

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

Ho provato in psql, non funziona. Devo elencare ogni colonna in questo modo:

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

tableBviene creato uso create .. like tableA. Quindi sono sostanzialmente identici. E il motivo per cui lo sto facendo è che devo caricare i dati .csv in una tabella temporanea tableBe quindi aggiornarli in tableAbase ai nuovi dati in tableB. tableAdeve essere bloccato il meno possibile e tableAdeve mantenere l'integrità. Non sono sicuro che 'Elimina quindi Inserisci' sarebbe una buona opzione?


1
Ho provato con il tuo secondo codice, funziona! Dovresti esaminare due argomenti: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Luan Huynh

Risposte:


12

Non esiste una variante di sintassi che ti consente di aggiornare l'intera riga contemporaneamente. Tuttavia, esiste una forma più breve di quella che hai finora.

Inoltre, in realtà non si desidera aggiornare tutte le colonne. La WHEREcondizione su ID indica almeno una colonna ( id) di rimanere invariata. Ma questo è solo un pignolo.

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

Maggiori dettagli in questa risposta correlata:
aggiornamento in blocco di tutte le colonne

DELETE / INSERT

Internamente, grazie al modello MVCC di Postgres , ognuno UPDATEinserisce comunque una nuova riga in modo efficace e segna quella vecchia come obsoleta. Quindi, dietro le tende non c'è molta differenza tra UPDATEe DELETEpiù INSERT.
Ci sono alcuni dettagli a favore del UPDATEpercorso:

  • AGGIORNAMENTO CALDO.
  • Tabelle TOAST: se si dispone di colonne di grandi dimensioni, il contenuto può essere archiviato. "Fuori linea" nelle tabelle TOAST e la nuova versione della riga può collegarsi alla stessa riga nella tabella TOAST se le colonne tostate rimangono invariate.
  • La manutenzione dell'indice potrebbe essere più economica per gli aggiornamenti.

Altrimenti, il bloccaggio dovrebbe essere più o meno lo stesso. È necessario un blocco esclusivo per le righe interessate in entrambi i modi. Fallo veloce.
Se hai a che fare con un numero enorme di righe e non hai bisogno di uno stato coerente (tutte le righe o nessuna), puoi dividere l'operazione in più batch. (Separare le transazioni!) Aumenta il costo totale, ma riduce il tempo di blocco per riga.


3
DELETE / INSERTpuò anche avere effetti indesiderati o semplicemente diversi (a cascata o innescati) rispetto a UPDATE.
ypercubeᵀᴹ

È corretto ma è necessario aggiornare la parte alias di table_a. table_a (che è tabella aggiornata) non può ottenere un alias.
Solo un altro amante del codice
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.