UPDATE: cómo modificar filas existentes en SQLite
INSERT agrega filas nuevas. UPDATE cambia filas que ya están en la tabla. La estructura es corta y conviene memorizarla:
UPDATE table_name
SET column = value
WHERE condition;
Un ejemplo práctico:
SET indica qué cambia. WHERE indica qué filas. El resto de la tabla queda intacto.
En la práctica, el WHERE no es opcional
Técnicamente, el WHERE es opcional. En la práctica, omitirlo es la receta perfecta para que un junior se arruine la tarde:
UPDATE users SET status = 'inactive';
-- ahora todos los usuarios están inactivos
Si no hay filtro, todas las filas coinciden. SQLite te va a obedecer sin rechistar. Acostúmbrate a escribir primero el WHERE y después el SET — solo con ese hábito te ahorras un montón de disgustos.
Si tienes dudas de que tu WHERE esté bien, prueba antes la misma condición con un SELECT:
Misma condición, dos sentencias. El SELECT te sirve como ensayo previo.
Actualizar varias columnas a la vez
Las asignaciones se separan con comas dentro de un único SET. Un solo SET, todas las columnas que necesites:
Una sola ida y vuelta a la base de datos, una fila modificada, tres columnas actualizadas. No escribas tres sentencias UPDATE separadas si con una basta.
Expresiones a la derecha del =
El valor que va después del = no tiene por qué ser un literal. Puede ser cualquier expresión, incluso una que use el valor actual de la columna:
price * 1.10 toma el precio actual, lo multiplica y guarda el resultado de nuevo. SQLite evalúa la parte derecha usando los valores actuales de la fila antes de aplicar cualquier asignación de esta sentencia, así que puedes referenciar varias columnas sin problema:
UPDATE products SET price = price * 1.10, stock = stock + price;
-- 'price' en el lado derecho aquí es el precio ANTIGUO, no el recién actualizado.
UPDATE ... FROM: traer valores desde otra tabla
Desde SQLite 3.33, la sentencia UPDATE admite la cláusula FROM, lo que permite hacer actualizaciones entre tablas. Es la forma más limpia de sincronizar datos entre dos tablas:
La subconsulta calcula los totales por cliente; el UPDATE exterior reincorpora esos resultados a customers usando id. Sin UPDATE ... FROM tendrías que escribir una subconsulta correlacionada por cada columna, lo cual ensucia bastante el código.
Algunas reglas a tener presentes:
- La tabla objetivo va después de
UPDATE, no dentro delFROM. - El join se hace en la cláusula
WHERE: aquí no existe la palabra claveON. - Si el join puede emparejar más de una fila en el
FROM, el resultado queda sin definir. Asegúrate de que las claves del join produzcan como mucho una coincidencia por fila objetivo.
RETURNING: ver qué cambió tras el UPDATE
SQLite (3.35+) permite que un UPDATE devuelva las filas modificadas en la misma sentencia. Resulta muy útil cuando tu aplicación necesita los valores ya actualizados sin lanzar después un SELECT adicional:
Recibes de vuelta las filas que realmente se modificaron, ya con sus nuevos valores. Te ahorras un viaje extra a la base de datos y eliminas toda una categoría de condiciones de carrera en código concurrente. Más adelante en este capítulo hay una página entera dedicada a RETURNING.
UPDATE OR REPLACE: cómo resolver conflictos de restricciones
Si tu UPDATE viola una restricción UNIQUE, el comportamiento por defecto es abortar la sentencia y lanzar un error. La cláusula OR te permite elegir otra política:
Las opciones son OR ABORT (la predeterminada), OR REPLACE, OR IGNORE, OR FAIL y OR ROLLBACK. La peligrosa es REPLACE: borra la fila en conflicto, lo que puede desencadenar borrados en cascada a través de claves foráneas. Úsala solo cuando de verdad quieras decir "si ya existe una fila con este valor único, deshazte de ella".
Para los casos típicos de upsert, la sintaxis dedicada INSERT ... ON CONFLICT resulta más clara. Hay una página aparte dedicada a ese tema.
Envuelve los UPDATE delicados en una transacción
Cuando vayas a modificar muchas filas o a ejecutar varias sentencias UPDATE que deben tener éxito en bloque, envuélvelas en una transacción. Así, si algo sale mal, puedes hacer rollback y volver al estado anterior:
Si la segunda sentencia falla (por ejemplo, salta una restricción), el ROLLBACK deshace la primera. Sin transacción, te quedarías con una transferencia a medias: Ada con 25 menos y Boris intacto. Las transacciones tienen su propio capítulo más adelante; por ahora basta con saber que existen y que las actualizaciones masivas casi siempre deberían ir dentro de una.
Errores frecuentes al actualizar registros en SQLite
Una lista corta de cosas con las que la gente tropieza:
- Olvidar el
WHERE: actualiza todas las filas. Lee la sentencia en voz alta antes de ejecutarla. - Operador equivocado en el
WHERE:WHERE status = NULLno coincide con nada. UsaIS NULL. Lo veremos en la página de operadores. - Actualizar con una subconsulta que devuelve más de una fila cuando esperabas una sola. Usa
LIMIT 1o agrega la subconsulta, o tendrás errores o resultados inesperados. - Confundir UPDATE OR REPLACE con UPSERT.
OR REPLACEborra las filas en conflicto.INSERT ... ON CONFLICT DO UPDATElas modifica en su sitio. Son operaciones distintas.
Lo siguiente: DELETE
UPDATE modifica filas; DELETE las elimina. Aplica la misma disciplina con el WHERE, y la misma costumbre de "lanzar primero un SELECT" te salvará del mismo tipo de desastres. Eso es lo que veremos en la siguiente página.
Preguntas frecuentes
¿Cuál es la sintaxis básica de UPDATE en SQLite?
UPDATE nombre_tabla SET columna = valor WHERE condicion;. En el SET indicas qué columnas quieres cambiar y sus nuevos valores. El WHERE decide qué filas se modifican; si lo omites, actualizas TODAS las filas de la tabla (y ahí empiezan los problemas).
¿Cómo actualizo varias columnas en una sola sentencia?
Separa las asignaciones con comas dentro del mismo SET: UPDATE users SET name = 'Ada', email = 'ada@x.com' WHERE id = 1;. Una sola sentencia, una sola ida a la base de datos y una fila modificada. No hace falta repetir SET para cada columna.
¿Se puede actualizar una tabla a partir de otra en SQLite?
Sí. Desde SQLite 3.33 tienes UPDATE ... FROM, que permite unir otra tabla o subconsulta dentro del UPDATE. La forma típica es UPDATE destino SET col = origen.col FROM origen WHERE destino.id = origen.id;. Es la manera más limpia de copiar valores entre tablas.