Skip to content

Haz upsert de una fila (INSERT o UPDATE en una sola sentencia) snippet

Un upsert inserta la fila si no existe y la actualiza si existe — en UNA sola sentencia, sin la carrera de leer y luego escribir.

Un upsert inserta la fila si no existe y la actualiza si existe — en UNA sola sentencia, sin la carrera de leer y luego escribir. El ingenuo de dos pasos (SELECT y luego INSERT o UPDATE) corrompe datos bajo concurrencia: dos escritores fallan ambos en el SELECT y ambos insertan. ON CONFLICT es la respuesta de Postgres; MySQL lo escribe ON DUPLICATE KEY UPDATE y SQLite copia la sintaxis de Postgres. Dos cosas deciden la corrección: el objetivo del conflicto debe ser una restricción unique o clave primaria real, y DO UPDATE necesita la pseudotabla excluded.* para leer los valores que fallaron al insertar.

Receta ejecutable · 1 lenguajes
Files & Datasqlupsertinserton-conflictpostgres

Every language

1 lenguajes, copy-ready. One at a time with syntax highlighting, or all inline.

SQLSQLrunnable
INSERT INTO users (id, email, name)
VALUES (42, 'ada@example.com', 'Ada')
ON CONFLICT (id) DO UPDATE
    SET email = excluded.email,
        name  = excluded.name
RETURNING id, (xmax = 0) AS inserted_this_time;

excluded holds the row that failed to insert — read the challenger's values from it, not from the table. ON CONFLICT DO NOTHING is the ignore-duplicates variant. Run it twice in the playground: first pass inserts (true), second pass updates (false).

Run in the SQL playground →

Keep going

Read the database-objects cheatsheet →