En el ciclo de vida de los datos, llega un momento en que cierta información ya no es necesaria. A veces, las relaciones se rompen, los productos se descatalogan y los usuarios se dan de baja.
Para eliminar registros de una tabla, utilizamos la sentencia DELETE.
Esta sentencia sirve para eliminar una o más filas de una tabla en una base de datos.
Si con UPDATE os dije que precaución, con DELETE os pido pánico.
Un borrado accidental es irreversible (toca ir a copia de seguridad, si la tienes)
Sintaxis básica
La sentencia DELETE es engañosamente simple. Solo necesitamos decir de qué tabla queremos borrar, y de ella qué filas.
DELETE FROM NombreTabla
WHERE Condicion;
- NombreTabla: Especifica la tabla de la cual se eliminarán las filas.
- Condicion: Define qué filas se eliminarán.
Por ejemplo, para borrar al cliente con ID 50:
DELETE FROM Clientes
WHERE ClienteID = 50;
Aquí no especificamos columnas. DELETE borra filas completas. No puedes borrar “solo esta y esta celda”.
Si quieres borrar un dato específico pero mantener la fila, hay que usar UPDATE para ponerlo a NULL (o cero, o vacio, si no es nualable).
El apocalipsis del WHERE olvidado
Por si no había quedado claro con el cartel del antes MUCHISIMO CUIDADO.
Si ejecutas un DELETE sin una cláusula WHERE, SQL Server entenderá que tu intención es borrar TODAS las filas de la tabla.
-- ☢️ ZONA CATASTRÓFICA
-- Esto dejará la tabla Clientes vacía en milisegundos
DELETE FROM Clientes;
Al igual que en el UPDATE. No te va a preguntar. No va a ser cortés. No hay papalera de reciclaje. La borrará, y fin, se acabó 🚨.
Al igual que con la UPDATE, es buena práctica escribir primero un SELECT con la condición para verificar qué vas a borrar, antes de cambiarlo por un DELETE y ejecutarlo definitivamente.
🎵 No te olvides de poneeer el wheeeere en el deleteeee frooooom 🎵
DELETE basado en otras tablas
A veces queremos borrar registros basándonos en información que reside en otra tabla. Imaginad que queremos borrar todos los Pedidos de los clientes que sean de “Teruel”.
En SQL estándar ANSI tendríamos que usar una subconsulta (WHERE ClienteID IN (SELECT…)). Pero T-SQL nos permite una sintaxis mucho más legible usando JOIN directamente en el borrado.
DELETE P
FROM Pedidos P
INNER JOIN Clientes C ON P.ClienteID = C.ClienteID
WHERE C.Ciudad = 'Teruel';
Fíjate en el detalle:
- Escribimos
DELETE P(usando el alias de la tabla que queremos limpiar). - Usamos
FROMyJOINpara relacionar las tablas. - Filtramos por la columna de la tabla unida.
Integridad referencial y el bloqueo de borrad
Si intentas borrar un Cliente que tiene Pedidos asociados, y existe una restricción de Clave Foránea, SQL Server detendrá la operación y te dará un error.
The DELETE statement conflicted with the REFERENCE constraint…
Aquí es donde las Foreign Keys que definimos en el Módulo 2 demuestran su valor.
Esto ocurre para proteger la consistencia de los datos. No podemos dejar los pedidos “huérfanos”. Para poder borrar a ese cliente, tienes dos opciones:
- Manual: Borrar primero sus pedidos y luego al cliente.
- Cascada: Si la FK se configuró con
ON DELETE CASCADE, al borrar al cliente, SQL Server borrará automáticamente todos sus pedidos. (Usad esto con extrema precaución).
Borrado Lógico vs Borrado Físico
En el mundo real, especialmente en sistemas empresariales, rara vez usamos DELETE .
Porque los datos son valiosos. Borrar algo significa perder su histórico y a veces romper cosas.
¿Qué pasa si el cliente vuelve? ¿Qué pasa si necesitamos auditar qué compró hace un año? ¿Qué pasa con todos los registros relacionados?
En su lugar, aplicamos el patrón de Borrado lógico (Soft Delete). Es decir, que usamos un campo para saber si la fila se usa, o no se usa (pero no la borramos).
- Añadimos una columna a la tabla, llamada
ActivooFechaBaja. - En lugar de
DELETE, hacemos unUPDATEpara marcarlo como inactivo.
Por ejemplo,
-- En lugar de borrarlo físicamente:
-- DELETE FROM Empleados WHERE EmpleadoID = 10;
-- Lo damos de baja lógicamente:
UPDATE Empleados
SET Activo = 0, FechaBaja = GETDATE()
WHERE EmpleadoID = 10;
Luego, en todas nuestras consultas, recordamos filtrar por WHERE Activo = 1. Así mantenemos el histórico y permitimos “deshacer” el borrado simplemente cambiando el bit de nuevo.
