Tutorial completo de MySQL 8: instalación, administración, tipos de datos y backup (2026)

UPDATE modifica filas existentes y DELETE las elimina. Ambas instrucciones son peligrosas sin cláusula WHERE: un UPDATE o DELETE sin WHERE afecta a todas las filas de la tabla, y en modo autocommit (que es el predeterminado) no hay deshacer. La regla de oro es siempre probar el WHERE con un SELECT antes de ejecutar la modificación.

En este capítulo cubrimos UPDATE y DELETE con ejemplos prácticos, TRUNCATE para vaciar tablas, y el patrón de soft delete para producción.

UPDATE básico

-- Actualizar un campo (SIEMPRE con WHERE)
UPDATE productos SET precio = 54.99 WHERE id = 1;

-- Actualizar varios campos a la vez
UPDATE clientes SET ciudad = 'Bilbao', nombre = 'Ana Pérez' WHERE id = 1;

-- Actualizar con expresión matemática
UPDATE productos SET precio = ROUND(precio * 1.05, 2);  -- subir 5% a todos
UPDATE productos SET stock = stock - 1 WHERE id = 2;     -- decrementar stock

-- Antes de ejecutar el UPDATE, verificar qué filas afecta:
SELECT id, nombre, precio FROM productos WHERE id_categoria = 1;
-- Si el resultado es el esperado, ejecutar:
UPDATE productos SET precio = ROUND(precio * 1.05, 2) WHERE id_categoria = 1;

UPDATE con JOIN (MySQL)

-- Aplicar 5% de descuento a pedidos de clientes de Madrid
UPDATE pedidos p
JOIN clientes c ON c.id = p.id_cliente
SET p.total = ROUND(p.total * 0.95, 2)
WHERE c.ciudad = 'Madrid' AND p.estado = 'pendiente';

-- Actualizar el campo 'activo' de clientes que no han pedido nada en el último año
UPDATE clientes c
LEFT JOIN pedidos p ON p.id_cliente = c.id AND p.fecha >= NOW() - INTERVAL 1 YEAR
SET c.activo = FALSE
WHERE p.id IS NULL;

DELETE básico

-- Eliminar una fila por ID
DELETE FROM clientes WHERE id = 42;

-- Eliminar con condición compuesta
DELETE FROM pedidos WHERE estado = 'cancelado' AND fecha < '2024-01-01';

-- Verificar antes:
SELECT id, estado, fecha FROM pedidos WHERE estado = 'cancelado' AND fecha < '2024-01-01';
-- Si es lo que esperas, ejecutar el DELETE

DELETE con JOIN (MySQL)

-- Borrar las líneas de pedido de todos los pedidos cancelados
DELETE lp
FROM lineas_pedido lp
JOIN pedidos p ON p.id = lp.id_pedido
WHERE p.estado = 'cancelado';

-- Borrar tanto los pedidos como sus líneas en una sola instrucción
DELETE p, lp
FROM pedidos p
JOIN lineas_pedido lp ON lp.id_pedido = p.id
WHERE p.estado = 'cancelado' AND p.fecha < '2024-01-01';

TRUNCATE: vaciar una tabla

-- Elimina TODAS las filas y resetea AUTO_INCREMENT a 1
-- Mucho más rápido que DELETE sin WHERE en tablas grandes
TRUNCATE TABLE lineas_pedido;

-- Diferencias con DELETE:
-- TRUNCATE no se puede usar dentro de una transacción en MySQL (es DDL)
-- TRUNCATE no dispara triggers ON DELETE
-- TRUNCATE no puede hacerse si hay FKs apuntando a la tabla (con ON DELETE RESTRICT)

Soft delete: el patrón para producción

En producción rara vez se borra físicamente. Lo habitual es marcar el registro como eliminado con una columna deleted_at:

-- Añadir la columna a tablas existentes
ALTER TABLE clientes ADD COLUMN deleted_at DATETIME NULL DEFAULT NULL;

-- Soft delete: no borra, solo marca
UPDATE clientes SET deleted_at = NOW() WHERE id = 42;

-- Todas las consultas deben filtrar los eliminados
SELECT * FROM clientes WHERE deleted_at IS NULL;

-- Recuperar un cliente eliminado
UPDATE clientes SET deleted_at = NULL WHERE id = 42;

-- Ver historial completo (incluyendo eliminados)
SELECT *, IF(deleted_at IS NOT NULL, 'eliminado', 'activo') AS estado
FROM clientes ORDER BY id;

La ventaja del soft delete es la trazabilidad y la posibilidad de recuperación. La desventaja es que todas las consultas deben incluir WHERE deleted_at IS NULL, lo que puede olvidarse y provocar que aparezcan datos eliminados.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP