La necesidad de registrar filas erróneas durante la importación masiva surgió casi inmediatamente después del surgimiento de cargas automáticas de grandes volúmenes de datos en bases de datos. Tradicionalmente, cualquier violación de restricciones (por ejemplo, violaciones de tipos de datos, restricciones) conducía a la interrupción de todo el proceso de importación incluso por una sola fila errónea, lo que resultaba en la pérdida de registros tanto correctos como incorrectos.
El problema radica en no solo cargar la máxima cantidad de datos correctos, sino también dejar una auditoría y una descripción detallada de los errores para una posterior corrección manual, en lugar de simplemente "revertir todo".
Solución: Para algunos SGBD (por ejemplo, PostgreSQL, SQL Server con SSIS, Oracle con utilidades EXTERNAL TABLES) existen mecanismos de carga que dividen las filas defectuosas. Para un método universal, se utilizan tablas de staging y validación post-carga a través de OUTER JOIN y NOT EXISTS, así como tablas de "log" asociadas, donde se escriben manualmente las filas problemáticas.
Ejemplo de código:
-- 1. Cargamos todo en una tabla de staging temporal BULK INSERT staging_payments FROM 'payments.csv' WITH (...) -- 2. Filtramos los correctos INSERT INTO payments (id, amount, ...) SELECT id, amount, ... FROM staging_payments WHERE amount > 0 AND status IN ('approved', 'pending'); -- 3. Registramos filas erróneas en una tabla separada INSERT INTO import_errors (row_data, error_desc) SELECT *, 'Estado incorrecto o suma negativa' FROM staging_payments WHERE amount <= 0 OR status NOT IN ('approved', 'pending');
Características clave:
¿Se puede implementar todo a través de ON ERROR RESUME NEXT dentro de SQL?
El estándar SQL no contiene tal construcción para importaciones masivas de operaciones. En la mayoría de los casos, el informe de errores se genera en utilidades externas o en tablas de log, como se describió anteriormente.
¿Se puede usar una transacción para revertir solo filas erróneas?
La reversión de una transacción revierte todas las filas a la vez (atomicidad). La conservación parcial es posible solo al cargar primero en una tabla de staging, después de lo cual manualmente se realiza commit de filas exitosas y log de las no exitosas.
¿Por qué no es efectivo capturar cada error de INSERT a través de TRY/CATCH en un ciclo para cada fila?
El procesamiento secuencial de millones de filas a través de inserciones individuales + TRY/CATCH conduce a una caída catastrófica en el rendimiento en comparación con la inserción por lotes o BULK INSERT + verificación después de la carga.
La empresa cargaba decenas de miles de filas a través de un script de INSERT, y cuando ocurría un error por clave única, toda la partida se revertía. Esto causaba inactividad y pérdida de datos.
Pros:
El uso de una tabla de staging, el registro de errores y la separación de los datos entrantes en categorías "válidas/no válidas" permitió acelerar la importación, almacenar y analizar automáticamente los rechazos.
Pros: