Ejecutar un DELETE con respaldo lógico y reversión controlada
Una corrección requiere retirar movimientos de inventario identificados y anteriores a una fecha. Además de comprobar el filtro, necesitamos conservar una copia recuperable si la eliminación llega a confirmarse.
Qué necesitamos distinguir
Un respaldo lógico copia las filas seleccionadas dentro de otra tabla; no sustituye un respaldo completo de la base. El identificador de lote agrupa las filas copiadas por una misma ejecución.
La vista previa, el respaldo y la eliminación deben referirse al mismo conjunto. Utilizaremos un identificador de lote para conservar las filas en una tabla permanente y confirmaremos el respaldo y el DELETE dentro de una sola transacción, una unidad que se confirma o revierte completa.
Consulta
/*
Antes de ejecutar:
Revisa la base activa, los nombres de objetos, los parámetros y los permisos.
Adapta el ejemplo a tu modelo y pruébalo primero en un ambiente controlado.
Los cambios se revierten de forma predeterminada.
Mantén @ConfirmarCambios = 0 hasta validar el alcance.
*/
SET NOCOUNT ON;
GO
-- Consulta
DECLARE @FechaLimite DATETIME2(0) = '2026-01-01T00:00:00';
DECLARE @Referencia NVARCHAR(100) = N'Carga temporal';
DECLARE @MaximoFilas INT = 100;
DECLARE @ConfirmarCambios BIT = 0;
DECLARE @IdLote UNIQUEIDENTIFIER = NEWID();
IF OBJECT_ID(N'dbo.RespaldoMovimientoInventario', N'U') IS NULL
THROW 50010, N'No existe la tabla de respaldo requerida.', 1;
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO dbo.RespaldoMovimientoInventario
(
IdLote, FechaRespaldo, IdMovimiento, IdProducto,
TipoMovimiento, Cantidad, FechaMovimiento, Referencia
)
SELECT
@IdLote, SYSDATETIME(), mi.IdMovimiento, mi.IdProducto,
mi.TipoMovimiento, mi.Cantidad, mi.FechaMovimiento, mi.Referencia
FROM dbo.MovimientoInventario AS mi WITH (UPDLOCK, HOLDLOCK)
WHERE mi.FechaMovimiento < @FechaLimite
AND mi.Referencia = @Referencia;
DECLARE @FilasObjetivo INT = @@ROWCOUNT;
IF @FilasObjetivo > @MaximoFilas
THROW 50011, N'El DELETE supera el máximo de filas esperado.', 1;
SELECT
r.IdLote,
r.IdMovimiento,
r.IdProducto,
r.TipoMovimiento,
r.Cantidad,
r.FechaMovimiento,
r.Referencia
FROM dbo.RespaldoMovimientoInventario AS r
WHERE r.IdLote = @IdLote
ORDER BY r.IdMovimiento;
DELETE mi
OUTPUT
@IdLote,
deleted.IdMovimiento,
deleted.IdProducto,
deleted.FechaMovimiento
FROM dbo.MovimientoInventario AS mi
INNER JOIN dbo.RespaldoMovimientoInventario AS r
ON r.IdLote = @IdLote
AND r.IdMovimiento = mi.IdMovimiento;
IF @@ROWCOUNT <> @FilasObjetivo
THROW 50012, N'Cambió el número de filas durante el DELETE.', 1;
IF @ConfirmarCambios = 1
COMMIT TRANSACTION;
ELSE
ROLLBACK TRANSACTION;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION;
THROW;
END CATCH;
GO
Parámetros o permisos
La tabla dbo.RespaldoMovimientoInventario debe existir antes de la corrección, con las columnas mostradas y una llave que impida repetir IdLote e IdMovimiento. Debe formar parte de la política autorizada de conservación, acceso y eliminación de respaldos. Adapta filtros y límite. El ejemplo revierte por defecto. Requiere lectura y eliminación en la tabla original, inserción y lectura en la tabla de respaldo, y visibilidad de metadatos para la comprobación inicial.
Cómo leer el resultado
La primera consulta muestra el conjunto que ya fue copiado bajo un lote único, antes de ejecutar el DELETE. La eliminación se une a ese mismo lote y no vuelve a calcular el filtro. Las comprobaciones detienen la operación si cambia la cantidad. Si se ejecuta ROLLBACK, tanto la eliminación como el respaldo de ese intento se revierten y las filas originales permanecen. Si se confirma, el respaldo y la eliminación persisten juntos. La consulta final permite revisar la copia antes de tomar esa decisión. Una tabla temporal o una variable de tabla sirve para inspeccionar, pero no conserva un respaldo después de cerrar la sesión. OUTPUT por sí solo tampoco es una estrategia durable.
Qué conclusión sí permite obtener
Permite demostrar qué filas integran el lote, conservarlas en una tabla permanente y comprobar que el mismo número fue eliminado dentro de una transacción.
Qué conclusión todavía no permite obtener
No garantiza una restauración completa si existen tablas relacionadas, triggers o efectos externos. Una FK puede impedir el borrado y una cascada puede afectar filas no incluidas en este respaldo.
Siguiente comprobación razonable
Prueba una restauración por IdLote en un ambiente controlado. Revisa relaciones, triggers, auditoría, retención y permisos antes de confirmar una eliminación en producción.