UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
Implemente inserções idempotentes com ON CONFLICT DO UPDATE, use EXCLUDED e escolha o alvo de conflito correto.
UPSERT: ON CONFLICT DO UPDATE (PostgreSQL) é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Academy inclui 4 aulas no total.
O que é UPSERT?
UPSERT = INSERT se não existir, UPDATE se existir. O PostgreSQL escreve isso como INSERT ... ON CONFLICT.
ON CONFLICT DO NOTHING
Insira se estiver ausente; ignore silenciosamente se for duplicado:
INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO NOTHING;ON CONFLICT DO UPDATE
Insira se estiver ausente; caso contrário, atualize colunas específicas:
INSERT INTO users (email, full_name, last_login)
VALUES ('alice@example.com', 'Alice', NOW())
ON CONFLICT (email)
DO UPDATE SET
full_name = EXCLUDED.full_name,
last_login = EXCLUDED.last_login;EXCLUDED: a linha proposta
Dentro de DO UPDATE, EXCLUDED.col significa "o valor que o INSERT tentou inserir". O nome simples da coluna (ou users.col) significa a linha existente.
ON CONFLICT (email)
DO UPDATE SET visits = users.visits + 1,
last_seen = EXCLUDED.last_seen;O alvo do conflito
Você deve indicar uma restrição UNIQUE ou uma chave primária:
ON CONFLICT (email) -- column with UNIQUE
ON CONFLICT (user_id, day) -- composite UNIQUE
ON CONFLICT ON CONSTRAINT users_email_key -- by nameUPSERT condicional (WHERE em DO UPDATE)
Atualize somente quando uma condição for atendida:
INSERT INTO inventory (product_id, qty)
VALUES (42, 5)
ON CONFLICT (product_id)
DO UPDATE SET qty = inventory.qty + EXCLUDED.qty
WHERE inventory.qty + EXCLUDED.qty <= 1000;UPSERT de várias linhas
Insira várias linhas; cada linha será tratada separadamente:
INSERT INTO page_views (path, day, count)
VALUES ('/home', CURRENT_DATE, 1), ('/about', CURRENT_DATE, 1)
ON CONFLICT (path, day)
DO UPDATE SET count = page_views.count + EXCLUDED.count;RETURNING com UPSERT
Obtenha a linha resultante, tenha ela sido inserida ou atualizada:
INSERT INTO users (email, full_name)
VALUES ('alice@example.com', 'Alice')
ON CONFLICT (email) DO UPDATE
SET full_name = EXCLUDED.full_name
RETURNING id, full_name;Fluxos de trabalho idempotentes
UPSERT torna as tentativas repetidas seguras. Se o seu gancho da web for acionado duas vezes, a segunda chamada atualizará a mesma linha em vez de criar uma duplicata.
MERGE (padrão SQL, PG15+)
O PostgreSQL 15 adicionou o MERGE, conforme o padrão SQL, que pode executar INSERT, UPDATE e DELETE em uma única instrução:
MERGE INTO users AS u
USING (VALUES ('alice@example.com','Alice')) AS src(email, name)
ON u.email = src.email
WHEN MATCHED THEN UPDATE SET full_name = src.name
WHEN NOT MATCHED THEN INSERT (email, full_name) VALUES (src.email, src.name);Quando não usar UPSERT
UPSERT exige uma restrição UNIQUE. Se você não tiver uma, normalmente deverá fazer um SELECT separado e depois INSERT ou UPDATE — mas fique atento às condições de corrida; envolva a operação em uma transação com bloqueio adequado.
Recapitulação
ON CONFLICT é o UPSERT limpo e atômico do PostgreSQL.
- DO NOTHING para "inserir se estiver ausente"
- DO UPDATE para um UPSERT verdadeiro
EXCLUDED= a linha proposta- Sempre indique um alvo de conflito
Verificação rápida
Em ON CONFLICT (email) DO UPDATE SET last_login = EXCLUDED.last_login, a que EXCLUDED se refere?
Perguntas Frequentes
A aula “UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)” é grátis?
Sim — o texto completo de “UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Academy, atualize para CoddyKit PRO. O curso de SQL Academy inclui 4 aulas no total.
O que vou aprender em “UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)”?
Implemente inserções idempotentes com ON CONFLICT DO UPDATE, use EXCLUDED e escolha o alvo de conflito correto. Você pratica SQL Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar SQL Academy?
Nenhuma experiência prévia é necessária. SQL Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de SQL Academy?
Sim. Cada aula de SQL Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- INSERT com várias linhas
- UPSERT: ON CONFLICT DO UPDATE (PostgreSQL)
- UPDATE com FROM e atualizações no estilo JOIN
- DELETE com USING e padrões seguros