Atualizar todas as colunas de outra tabela

13

Preciso atualizar uma tabela de outra e preciso atualizar todas as colunas. Além de listar todas as colunas da SETcláusula, existe uma maneira de atualizá-las todas de uma vez? Como isso:

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

Eu tentei no psql, não funciona. Eu tenho que listar todas as colunas como esta:

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

tableBé criado, use create .. like tableA. Então eles são basicamente idênticos. E a razão pela qual estou fazendo isso é que preciso carregar dados .csv em uma tabela temporária tableBe atualizar com tableAbase nos novos dados do tableB. tableAprecisa ser bloqueado o menos possível e tableAprecisa manter a integridade. Não tenho certeza 'excluir e inserir' seria uma boa opção?

odieatla
fonte
1
Eu testei com o seu segundo código, funciona! Você deve revisar dois tópicos: dba.stackexchange.com/questions/58371/… , dba.stackexchange.com/questions/59458/…
Luan Huynh

Respostas:

12

Não variante de sintaxe que permita atualizar a linha inteira de uma só vez. No entanto, existe uma forma mais curta do que a que você tem até agora.

Além disso, você realmente não deseja atualizar todas as colunas. A WHEREcondição nos pinos de identificação pressiona pelo menos uma coluna ( id) para permanecer inalterada. Mas isso é apenas nitpicking.

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

Mais detalhes nesta resposta relacionada:
Atualização em massa de todas as colunas

DELETE / INSERT

Internamente, devido ao modelo MVCC do Postgres , todos UPDATEefetivamente inserem uma nova linha de qualquer maneira e marcam a antiga como obsoleta. Portanto, por trás das cortinas, não há muita diferença entre UPDATEe DELETEmais INSERT.
Existem alguns detalhes a favor da UPDATErota:

  • ATUALIZAÇÃO QUENTE.
  • Tabelas TOAST: se você tiver colunas grandes, o conteúdo poderá ser armazenado "fora de linha" nas tabelas TOAST e a nova versão da linha poderá vincular à mesma linha na tabela TOAST se as colunas torradas permanecerem inalteradas.
  • A manutenção do índice pode ser mais barata para atualizações.

Caso contrário, o bloqueio deve ser praticamente o mesmo. Você precisa de um bloqueio exclusivo nas linhas afetadas de qualquer maneira. Apenas seja rápido.
Se você estiver lidando com um grande número de linhas e não precisar de um estado consistente (todas as linhas ou nenhuma), poderá dividir a operação em vários lotes. (Transações separadas!) Aumenta o custo total, mas reduz o tempo de bloqueio por linha.

Erwin Brandstetter
fonte
3
DELETE / INSERTtambém pode ter efeitos indesejados ou apenas diferentes (em cascata ou disparados) que os UPDATE.
precisa saber é o seguinte
Está correto, mas você deve atualizar o alias parte de table_a. table_a (que é tabela atualizada) não pode obter um alias.
Apenas outro amante do código