A pergunta é antiga, mas eu senti que a melhor resposta ainda não havia sido dada.
Existe uma UPDATE
sintaxe ... sem especificar os nomes das colunas ?
Solução geral com SQL dinâmico
Você não precisa saber nenhum nome de coluna, exceto algumas colunas exclusivas para ingressar ( id
no exemplo). Funciona de forma confiável para qualquer possível gabinete de canto em que eu possa pensar.
Isso é específico do PostgreSQL. Estou construindo código dinâmico com base no information_schema , em particular na tabela information_schema.columns
, definida no padrão SQL e na maioria dos principais RDBMS (exceto Oracle). Mas uma DO
declaração com o código PL / pgSQL executando SQL dinâmico é uma sintaxe PostgreSQL totalmente fora do padrão.
DO
$do$
BEGIN
EXECUTE (
SELECT
'UPDATE b
SET (' || string_agg( quote_ident(column_name), ',') || ')
= (' || string_agg('a.' || quote_ident(column_name), ',') || ')
FROM a
WHERE b.id = 123
AND a.id = b.id'
FROM information_schema.columns
WHERE table_name = 'a' -- table name, case sensitive
AND table_schema = 'public' -- schema name, case sensitive
AND column_name <> 'id' -- all columns except id
);
END
$do$;
Assumindo uma coluna correspondente b
para cada coluna a
, mas não o contrário. b
pode ter colunas adicionais.
WHERE b.id = 123
é opcional, para atualizar uma linha selecionada.
SQL Fiddle.
Respostas relacionadas com mais explicações:
Soluções parciais com SQL simples
Com lista de colunas compartilhadas
Você ainda precisa conhecer a lista de nomes de colunas que as duas tabelas compartilham. Com um atalho de sintaxe para atualizar várias colunas - menor que o que as outras respostas sugeriram até agora em qualquer caso.
UPDATE b
SET ( column1, column2, column3)
= (a.column1, a.column2, a.column3)
FROM a
WHERE b.id = 123 -- optional, to update only selected row
AND a.id = b.id;
SQL Fiddle.
Essa sintaxe foi introduzida no Postgres 8.2 em 2006, muito antes da pergunta ser feita. Detalhes no manual.
Palavras-chave:
Com lista de colunas em B
Se todas as colunas de A
estiverem definidas NOT NULL
(mas não necessariamente B
)
e você souber os nomes das colunas de B
(mas não necessariamente A
).
UPDATE b
SET (column1, column2, column3, column4)
= (COALESCE(ab.column1, b.column1)
, COALESCE(ab.column2, b.column2)
, COALESCE(ab.column3, b.column3)
, COALESCE(ab.column4, b.column4)
)
FROM (
SELECT *
FROM a
NATURAL LEFT JOIN b -- append missing columns
WHERE b.id IS NULL -- only if anything actually changes
AND a.id = 123 -- optional, to update only selected row
) ab
WHERE b.id = ab.id;
A NATURAL LEFT JOIN
junta-se uma linha de b
onde todas as colunas com o mesmo nome segurar mesmos valores. Não precisamos de atualização neste caso (nada muda) e podemos eliminar essas linhas no início do processo ( WHERE b.id IS NULL
).
Ainda precisamos encontrar uma linha correspondente, portanto, b.id = ab.id
na consulta externa.
db <> mexe aqui
Old sqlfiddle.
Este é o SQL padrão, exceto a FROM
cláusula .
Funciona independentemente de qual das colunas estiver realmente presente A
, mas a consulta não pode distinguir entre valores NULL reais e colunas ausentes A
, portanto, só é confiável se todas as colunas A
estiverem definidas NOT NULL
.
Existem várias variações possíveis, dependendo do que você sabe sobre as duas tabelas.