PostgreSQL - Como fazer um UPSERT

Dessa vez irei mostrar como utilizar o recurso UPSERT no PostgreSQL, que nada mais é do que inserir ou atualizar os dados caso o registro que está sendo inserido já existe na tabela.

Essa cláusula foi inserida a partir da versão 9.5. Se você estiver usando uma versão anterior, você precisará de uma outra solução para ter esse recurso.

Em bancos de dados relacionais, o termo UPSERT é referido como uma fusão. A ideia é que, quando você insere um novo registro na tabela, o PostgreSQL atualizará o registro se ele já existir, caso contrário, o PostgreSQL insere o novo registro. É por isso que chamamos a ação de UPSERT (atualização ou inserção).

Demonstrarei esse recurso utilizando a instrução INSERT ON CONFLICT da seguinte maneira:

INSERT INTO table (columns) VALUES (values)
ON CONFLICT target action;

Onde target, pode ser:
  • (coluna) - um nome de coluna;

  • ON CONSTRAINT constraint - um nome de constraint;

  • WHERE predicado - uma cláusula WHERE com um predicado.

Onde action, pode ser:
  • DO NOTHING - significa não fazer nada se o registro já existe na tabela;

  • DO UPDATE SET column = value, .. WHERE condition - atualize alguns campos na tabela.

Para ON CONFLICT DO NOTHING, é opcional especificar uma restrição. Quando omitido, os conflitos com todas as restrições utilizáveis ​​(e índices exclusivos) são tratados.

Para ON CONFLICT DO UPDATE, uma restrição deve ser fornecida.

Agora vamos partir para a prática!

Para demonstrar a usabilidade desse recurso, iremos criar uma tabela e inserir alguns registros:

CREATE TABLE cliente
(
  id SERIAL NOT NULL,
  nome TEXT,
  CONSTRAINT pk_cliente PRIMARY KEY (id)
);

INSERT INTO cliente (nome) VALUES
  ('JOÃO'),
  ('MARIA'),
  ('JOSÉ');

Vamos fazer uma consulta trazendo todos os registros para conferir:

SELECT * FROM cliente;

id | nome    
---+-------
1  | JOÃO
2  | MARIA
3  | JOSÉ

(3 registros)

Agora vamos executar o seguinte comando:

INSERT INTO cliente VALUES (2, 'MARIAA')
ON CONFLICT (id)
DO
  UPDATE SET nome = 'MARIAA';

Vamos novamente fazer uma consulta:

SELECT * FROM cliente;

id | nome    
---+-------
1  | JOÃO
3  | JOSÉ
2  | MARIAA


(3 registros)

Note que ao tentar inserir, já existia um registro com o "id = 2", então houve um conflito e passou a executar uma atualização onde alterou o campo nome para "MARIAA".

Caso tenha alguma dúvida, deixe um comentário.

Comentários