Actualización de registros con UPDATE
UPDATE modifica valores de registros que ya existen. No agrega registros ni los elimina: los mismos registros siguen ahí, con algún dato distinto.
UPDATE socios
SET telefono = '221-5551234'
WHERE id = 47;
Tres partes, y las tres importan:
| Parte | Qué define | Qué pasa si falta |
|---|---|---|
UPDATE socios |
Qué tabla se modifica. | Error de sintaxis. |
SET telefono = ... |
Qué campos cambian y con qué valores. | Error de sintaxis: no se dice qué cambiar. |
WHERE id = 47 |
Qué registros se modifican. | Se modifican todos. Sin error y sin aviso. |
Fijate en la asimetría de la última fila. Si falta el SET, la base avisa y no ejecuta nada. Si falta el WHERE, la base hace exactamente lo que se le pidió: cambia ese campo en todos los registros. No hay advertencia, no hay confirmación, no hay vuelta atrás.
Para cambiar varios campos a la vez, se separan con comas dentro del mismo SET:
UPDATE socios
SET correo = '[email protected]',
telefono = '221-5551234'
WHERE id = 47;
NULL y que la condición apunta a un solo registro.
UPDATE cambia los dos campos de una vez y confirma que afectó una fila. Ese número es la comprobación de que el WHERE estuvo bien escrito.
Eliminación de registros con DELETE
DELETE FROM socios WHERE id = 47;
Es la más corta y tiene un detalle que a primera vista parece una inconsistencia: no dice qué se borra. No hay una lista de columnas como en el SELECT, ni un SET como en el UPDATE. Y no es un olvido: DELETE no borra valores, borra registros completos. Un registro al que le quedan algunos campos no es un registro: es un dato a medias. Cuando se da de baja algo, se lo da de baja entero.
Conviene no confundir las tres instrucciones que «borran», porque hacen cosas muy distintas:
| Instrucción | Qué elimina | La tabla después |
|---|---|---|
DELETE FROM socios |
Los registros. | Sigue existiendo, vacía. |
TRUNCATE TABLE socios |
Los registros, todos y de golpe. | Sigue existiendo, vacía. Más rápido, y reinicia el contador de AUTO_INCREMENT. |
DROP TABLE socios |
La tabla misma, con sus campos y sus reglas. | No existe. No hay dónde cargar socios hasta crear otra. |
Y un detalle que sorprende a quien viene de usar programas: después de un UPDATE o un DELETE, el gestor informa cuántos registros quedaron afectados —«1 fila afectada», «30 filas afectadas»—. Ese número hay que leerlo. Es la única señal que va a haber de que la sentencia hizo lo que se esperaba, o de que hizo mucho más. Un «247 filas afectadas» cuando se esperaba modificar una es la forma de enterarse de que el WHERE estaba mal escrito, todavía a tiempo de intentar arreglarlo.
La importancia del WHERE
WHERE, un UPDATE modifica todos los registros y un DELETE los borra todos. No es una advertencia teórica: le pasa a todo el mundo alguna vez, y es el error más destructivo que se puede cometer con SQL. En un gestor no hay deshacer, no hay papelera y no hay confirmación.
Vale entender por qué pasa, porque el motivo no es la distracción sino la forma en que se escribe la sentencia. Uno piensa primero qué quiere cambiar —el teléfono de Ana— y escribe el SET con eso. Después se acuerda de acotar a quién, y escribe el WHERE al final. Y en el medio hay un momento en que la sentencia está completa para el gestor pero no para uno: si se selecciona todo y se ejecuta en ese instante, ya no hay vuelta atrás.
La defensa es un cambio de hábito, y es simple: escribir primero la parte que acota. Antes de pensar en el SET o en el DELETE, escribir la condición. La sentencia queda incompleta —falta decir qué cambia— y el gestor se va a negar a ejecutarla. Es imposible ejecutar algo destructivo por accidente, porque no hay nada que ejecutar.
Y hay un segundo motivo por el que el WHERE de estas dos instrucciones es más delicado que el de un SELECT: un SELECT con la condición mal escrita devuelve un resultado equivocado, que se ve raro y se corrige. Un UPDATE con la condición mal escrita cambia los datos, y el resultado equivocado queda guardado. La misma línea de texto, dos consecuencias incomparables.
Verificación previa con una consulta SELECT
Acá está el método que evita el problema, y no cuesta nada. Es la aplicación de una idea sencilla: si la misma condición se prueba antes, la operación deja de ser a ciegas.
-- Paso 1: ¿a quiénes va a afectar? Se comprueba con un SELECT.
SELECT id, nombre, telefono FROM socios WHERE id = 47;
-- Paso 2: recién ahora, con la condición ya escrita y probada, la operación.
UPDATE socios SET telefono = '221-5551234' WHERE id = 47;
El SELECT del primer paso se escribe copiando el WHERE que se va a usar, y cumple tres funciones a la vez:
- Confirma que la condición identifica lo que uno cree. Si devuelve un registro, era eso lo que se buscaba. Si devuelve tres, la condición es más amplia de lo que se pensaba.
- Si devuelve cero, avisa antes de tocar nada. Una condición que no encuentra nada probablemente esté mal escrita: un nombre mal tipeado, un
idque no existe. En lugar de ejecutar una operación que no hace nada, uno se entera del problema. - Deja ver los valores actuales. Es lo único que permite saber si el cambio tiene sentido: quizá el teléfono ya era ese.
Para una operación masiva hay una variante que aporta más información todavía: contar los registros afectados antes.
-- ¿A cuántos va a afectar exactamente? Un número, no una lista.
SELECT COUNT(*) FROM socios WHERE activo = 0 AND alta < '2020-01-01';
Ese número es el que después hay que comparar con el «N filas afectadas» que informa el gestor. Si coinciden, la operación hizo lo previsto. Si no coinciden, algo pasó. Y para el caso extremo —una corrección masiva, un borrado por lote— existe una tercera red de seguridad que se vio en la Unidad 1: las transacciones. Encerrando la operación entre un inicio y un COMMIT, si el resultado no es el esperado se descarta todo con un ROLLBACK y los datos vuelven a como estaban. Para el trabajo diario no hace falta; para una operación que toca miles de registros, es la diferencia entre poder arrepentirse y no poder.
Resumen
UPDATE tabla SET campo = valor WHERE condiciónmodifica registros existentes.DELETE FROM tabla WHERE condiciónelimina registros completos: por eso no lleva lista de campos.- Sin
WHEREunUPDATEmodifica todo y unDELETEborra todo, sin aviso. DELETE FROMvacía la tabla pero la deja;TRUNCATEhace lo mismo más rápido;DROP TABLEelimina la tabla misma.- El «N filas afectadas» que informa el gestor hay que leerlo: es la única señal de que la sentencia hizo lo que se esperaba.
- El error pasa porque uno escribe primero qué cambia y después a quién: conviene escribir primero la condición.
- Un
SELECTmal filtrado devuelve un resultado raro; unUPDATEmal filtrado cambia los datos. - Antes de operar: probar la condición con un
SELECT. - Para operaciones masivas:
COUNT(*)antes y transacción conCOMMITyROLLBACK.