Curso de SQL completo: SELECT, JOIN, agregaciones, índices y transacciones (2026)

UPDATE modifica los valores de filas existentes; DELETE las elimina. Son las instrucciones más peligrosas de SQL: un UPDATE o DELETE sin WHERE afecta a todas las filas de la tabla, y una vez ejecutado en modo autocommit no hay vuelta atrás. La regla de oro es: siempre escribe y verifica el WHERE antes de ejecutar.

En este capítulo cubrimos UPDATE y DELETE con ejemplos, el patrón de verificación previa con SELECT, TRUNCATE como alternativa al DELETE sin WHERE, y los JOINs en UPDATE y DELETE (extensión MySQL).

UPDATE básico

-- Actualizar un solo campo
UPDATE productos SET precio = 54.99 WHERE id = 1;

-- Actualizar múltiples campos a la vez
UPDATE clientes
SET ciudad = 'Bilbao', nombre = 'Ana García Pérez'
WHERE id = 1;

-- Actualizar con expresión (subir el precio un 10%)
UPDATE productos SET precio = ROUND(precio * 1.10, 2)
WHERE id_categoria = 1;

-- Actualizar con la fecha actual
UPDATE pedidos SET estado = 'enviado', lastupdate = NOW()
WHERE id = 42;

Verificar antes de actualizar

Antes de ejecutar un UPDATE, convierte el WHERE en un SELECT para confirmar qué filas se van a afectar:

-- Primero: ¿qué filas voy a actualizar?
SELECT id, nombre, precio FROM productos WHERE id_categoria = 1;

-- Si el resultado es correcto, ejecutar el UPDATE:
UPDATE productos SET precio = ROUND(precio * 1.10, 2)
WHERE id_categoria = 1;

UPDATE con JOIN (MySQL)

-- Aplicar un 5% de descuento a los 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';

DELETE básico

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

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

-- ¡NUNCA hagas esto sin estar absolutamente seguro!
-- DELETE FROM productos;  ← borra TODOS los productos

DELETE con JOIN (MySQL)

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

-- Con múltiples tablas a la vez (MySQL permite borrar de varias tablas en un JOIN):
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: borrar todas las filas rápidamente

-- TRUNCATE elimina todas las filas y resetea el AUTO_INCREMENT
-- Es mucho más rápido que DELETE sin WHERE (no guarda log de cada fila)
-- NO se puede deshacer con ROLLBACK (en MySQL, TRUNCATE es DDL, no DML)
TRUNCATE TABLE pedidos;

-- DELETE sin WHERE: más lento, pero se puede deshacer con ROLLBACK
BEGIN;
DELETE FROM pedidos;
ROLLBACK;  -- los pedidos vuelven

Soft delete: marcar como eliminado sin borrar

-- Patrón habitual en producción: añadir columna 'deleted_at'
ALTER TABLE clientes ADD COLUMN deleted_at DATETIME NULL DEFAULT NULL;

-- "Borrar" un cliente (soft delete)
UPDATE clientes SET deleted_at = NOW() WHERE id = 42;

-- En todas las consultas, filtrar los eliminados:
SELECT * FROM clientes WHERE deleted_at IS NULL;

-- Ventajas: auditoría, posibilidad de recuperar, integridad referencial

Modo seguro en MySQL

MySQL Workbench activa por defecto el modo seguro (sql_safe_updates), que impide UPDATE y DELETE sin WHERE que incluya una columna indexada. En la CLI se puede activar manualmente para mayor seguridad:

SET sql_safe_updates = 1;
-- Ahora UPDATE/DELETE sin WHERE sobre columna indexada fallan con error 1175

COMPARTE ESTE ARTÍCULO

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