Problemas múltiplos.
Sua configuração, estendida:
CREATE TABLE a (
pk_a int PRIMARY KEY
, a int
, comment text -- added column to make effect clear
);
CREATE TABLE b (
pk_b int PRIMARY KEY
, b int
, comment text
);
INSERT INTO a VALUES (1, 11, 'comment from a')
, (2, 22, 'comment from a');
INSERT INTO b VALUES (1, 77, 'comment from b');
Isso funciona:
INSERT INTO b (pk_b, b, comment)
SELECT pk_a, a, comment
FROM a
ON CONFLICT (pk_b) DO UPDATE -- conflict is on the unique column
SET b = excluded.b; -- key word "excluded", refer to target column
Resultado:
TABLE b;
pk_b | b | comment
------+----+----------------
1 | 11 | comment from b -- updated
2 | 22 | comment from a -- inserted
Os problemas
Você está confuso table_a
e A
em sua demonstração (como o @Abelisto comentou ).
O uso de identificadores legais, em minúsculas e sem aspas ajuda a evitar confusões.
Como o @Ziggy mencionado , ON CONFLICT
funciona apenas para violações reais de restrição única ou de exclusão . O manual:
A ON CONFLICT
cláusula opcional especifica uma ação alternativa para gerar um erro exclusivo de violação de violação ou restrição de exclusão.
Conseqüentemente, ON CONFLICT (b)
não pode funcionar, sem restrições por lá. ON CONFLICT (pk_b)
trabalho.
Como o @Ziggy também mencionado , os nomes das tabelas de origem não são visíveis na UPDATE
peça. O manual:
As cláusulas SET
e têm acesso à linha existente usando o nome da tabela (ou um alias) e às linhas propostas para inserção usando a tabela especial .WHERE
ON CONFLICT DO UPDATE
excluded
Negrito ênfase minha.
Você também não pode usar nomes de colunas da tabela de origem na UPDATE
peça. Deve ser o nome da coluna da linha de destino . Então você realmente quer:
SET b = excluded.b
O manual mais uma vez:
Observe que os efeitos de todos os BEFORE INSERT
gatilhos por linha são refletidos em valores excluídos, pois esses efeitos podem ter contribuído para a linha ser excluída da inserção.
CREATE TABLE A...
cria tabelaa
, nãotable_a
.