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_ae Aem 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 CONFLICTfunciona apenas para violações reais de restrição única ou de exclusão . O manual:
A ON CONFLICTclá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 UPDATEpeça. O manual:
As cláusulas SETe têm acesso à linha existente usando o nome da tabela (ou um alias) e às linhas propostas para inserção usando a tabela especial .WHEREON CONFLICT DO UPDATEexcluded
Negrito ênfase minha.
Você também não pode usar nomes de colunas da tabela de origem na UPDATEpeç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 INSERTgatilhos 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.