Tema SQL
MERGE / UPSERT
Patrones para insertar una fila si la clave no existe o actualizarla si ya existe, o fusionar tablas origen/destino en una sola sentencia según motor.
Descripción
No hay un único estándar portable. MERGE en SQL Server/Oracle combina USING/WHEN MATCHED/WHEN NOT MATCHED. PostgreSQL usa INSERT … ON CONFLICT DO UPDATE (upsert). MySQL ofrece INSERT … ON DUPLICATE KEY UPDATE. SQLite tiene INSERT OR REPLACE u ON CONFLICT. Elige la forma soportada por tu motor y revisa condiciones de carrera bajo concurrencia (bloqueos o transacciones serializables). Define bien la clave única o primaria objetivo.
Estructura general
Forma habitual de la sentencia: orden de cláusulas, qué parte filtra, agrupa o proyecta columnas, y qué devuelve el motor. Cópiala como plantilla y sustituye nombres por tus tablas reales.
-- Patrón conceptual (varía por motor)
MERGE destino USING origen ON (clave)
WHEN MATCHED THEN UPDATE ...
WHEN NOT MATCHED THEN INSERT ...;
Componentes
Cada componente tiene un papel concreto en la ejecución lógica de la sentencia. Léelos en orden: así entiendes qué puedes omitir, qué es obligatorio y qué expresiones son válidas en cada sitio según tu motor.
- Motor
- Consulta la documentación oficial: nombres de cláusulas, columnas especiales (EXCLUDED en PostgreSQL) y efectos en triggers.
Ejemplos
Ejemplo 1
-- PostgreSQL (ejemplo ilustrativo)
INSERT INTO sync (id, valor)
VALUES (1, 'a')
ON CONFLICT (id) DO UPDATE SET valor = EXCLUDED.valor;
Ejemplo 2
-- Sintaxis específica del motor
Los ejemplos son ilustrativos. En producción usa consultas parametrizadas (prepared statements), revisa índices y aplica el principio de menor privilegio en cuentas de base de datos.