Depurar datos de una tabla con OUTPUT


En algunos sistemas disponemos de información en las tablas grandes que no se usan de forma frecuente. Para este tipo de situaciones existen varias alternativas de solución que van desde borrar o mover los datos a una base de history hasta la utilización de particiones dentro de la misma tabla (Edición Enterprise de SQL Server).

En este post nos vamos a dedicar a una de estas opciones que básicamente es mover los datos a otra base de datos. Supongamos que deseamos mover todas las órdenes menores a una determinada fecha a una base de datos de historia.

¿Que sucede cuando deseamos implementar algo así? , básicamente el problema es que debería borrar de la tabla origen los registros e insertarlos en la tabla destino, para ello se me podrían ocurrir distintos tipos de alternativas como por ejemplo:

Triggers: Se crea un Trigger para la operación Delete en la tabla origen, ese trigger tiene el código necesario que hace el INSERT en la base destino. Este mecanismo me asegura que cuando borro registros en la tabla origen se pasan a la destino, si falla no se pasan ya que están dentro de la misma transacción. Ahora bien, esta solución tiene un problema, el trigger se va a disparar no solo para mi proceso de depuración sino que para cualquier operación DELETE que se haga sobre la tabla, lo cual no resulta funcional a lo que deseo o bien de hacerlo debería agregar alguna lógica en el trigger lo cual podría hacer que las operaciones de DELETE se hagan más lentas.

Proceso de depuración: Otra opción es hacer este proceso de depuración con lógica TSQL, lo primero que deberíamos hacer es saber que registros borrar y por ejemplo guardarlos en una tabla temporal y luego esos ID empezar a borrarlos de la tabla origen e insertarlos en la tabla destino.

OUTPUT: Este es el mecanizo que usaremos en este post, la instrucción OUPUT existe desde SQL Server 2005 y permite obtener la salida de una operación de modificación como puede ser INSERT, UPDATE y DELETE.

Consideraciones adicionales para cualquier método: Cualquier proceso de depuración se debería hacer en lotes de registros ya que sino la transacción puede ser muy grande y esto generar otros problemas de performance en las aplicaciones. También sería recomendable decirle al SQL (si es que la tabla ya no lo tiene) que los loqueos no hagan un escalamiento lo cual podría pasar que por querer borrar 10.000 registros se termine bloqueando la tabla completa o páginas de otros registros que no están relacionados con mi depuración, si bien esto hará mas uso de la memoria del servidor y habrá que analizarlo en términos generales termina siendo una buena práctica.

Código ejemplo de cómo usar OUTPUT en un depurador: