Es muy común encontrarnos con escenarios en los que tenemos que consumir orígenes de datos que contienen duplicados, tanto por columnas clave como por filas completas. Integration Services ofrece componentes que permite eliminar los duplicados (componente Sort), pero en esta entrada vamos a centrarnos en un diseño que nos permita capturar las filas duplicadas por columnas clave para su posterior tratamiento, utilizando la menor cantidad de código posible (componente Script).

Escenario

Vamos a posicionarnos en un escenario en el que el origen de datos sea un archivo de texto que contiene duplicados por las columnas clave. El destino en el que queremos insertar los datos no permite duplicados y los requisitos de la solución exigen que los duplicados sean volcados en otra tabla para su revisión.

Solución propuesta

Existen diversas alternativas para conseguir el objetivo que nos hemos marcado, en nuestro caso queremos evitar escribir código si es posible.

El conjunto de datos con el que vamos a trabajar en este ejemplo proviene de un fichero de texto y contiene las siguientes filas.

image_thumb_1_44CAF960

Observamos que existen dos registros duplicados, los representados por los ID 1 y 5.

Tras crear y configurar el administrador de conexión para este origen de datos y dada la imposibilidad de obtener ordenado el conjunto, añadimos al flujo de datos un componente de ordenación (Sort) que configuramos para ordenar por la columna ID.

image_thumb_2_44CAF960

El siguiente paso consiste en añadir un componente Multicast para duplicar el flujo de datos. Con una de las salidas del multicast realizaremos la agrupación de los datos por la columna ID, añadiendo una columna agregada que nos devuelva el número de registros que se agrupan por cada ID que llamaremos “Duplicados”:

image_thumb_3_72B84C18

Conectamos un componente de división condicional (conditional split) y configuramos una salida que evalúe la columna “Duplicados” que generamos en el agrupado, haciendo que los valores >1 se redirijan a la salida “Duplicados” y la salida por omisión la denominamos “Únicos”:

image_thumb_4_72B84C18

Tomamos la salida “Unicos” que hemos creado en el conditional split y la conectamos con un nuevo componente Sort que añadimos al flujo de datos. Volvemos a ordenar por ID.

Finalmente añadimos un componente Merge Join, al que conectamos a la entrada izquierda otra salida del Multicast. En la entrada derecha del Join conectamos la salida ordenada de la ramificación del Multicast que agrupamos. Podemos configurar el Join como Inner y nos devolvería solo los registros únicos, pero también podemos establecerlo como Left Outer y también pasarían los duplicados:

image_thumb_5_72B84C18

Si elegimos esta última opción podemos agregar otro componente de división condicional para filtrar los duplicados y los únicos:

image_thumb_6_72B84C18

Finalmente añadimos un destino para cada salida de la división condicional. Para el ejemplo he añadido un componente de columna derivada en cada salida para poder conectar un dataview. Este es el aspecto de todo el diseño:

image_thumb_7_72B84C18

Y si ejecutamos el paquete obtenemos lo siguiente:

image_thumb_9_72B84C18

 

Otras aproximaciones

Otra alternativa es delegar en el componente de destino el tratamiento de duplicados, si la tabla de destino tiene configurada una clave primaria o un índice único que rechace las filas duplicadas. Esta aproximación es la misma que la explicada en la entrada Optimizando inserciones con el adaptador Destino OLEDB

También es posible realizar toda la operación de comparación de duplicados y redirección a través de un script component. Este caso lo tiene bien documentado Joost van Rossum en su blog

Si el origen fuera una base de datos que soportar lenguaje SQL podríamos obtener el conjunto de datos si duplicados desde la fuente, mediante el diseño de la consulta apropiada

 

Conclusión

Esta es una  de la multitud de soluciones que existen para gestionar este tipo de escenarios. Si tienes otra aproximación, compártela con nosotros para discutir pros y contras, siempre es enriquecedor ampliar conocimientos.

🙂

 

0 Shares:
3 comments
  1. Hola,yo considero que hay un escenario que no cubre muy bien SSIS, soy nuevo o uizas por ignorancia no se comos e hace, pero por que en el destino se puede validar si el registro que se inserta esta duplicado, y de hecho lo duplica, lo triplica cada que se corre la rutina y internet no hay nada que hable al respecto, sin embargo si yo desarrollo un servicio widnows que lo haga desde c#, me resulto mas rápido y confiable la solución. Es mi punto de vista tal vez lo digo por ignorancia. Saludos.

    1. Hola FerFierroPariente,
      Hay varias alternativas para averiguar si un registro existe en destino antes de insertarlo. Podemos hacer un lookup sobre el destino e insertar solo aquellos registros que no coincidan. Otra opción es hacer lo mismo con un Merge y aplicando un filtro con conditional split.
      Otra forma de lograr lo mismo es delegando el control en el destino, si el duplicado se controla por constraint (primary key o unique index) se puede controlar el error del batch a insertar y redirigirlo a otra inserción con batch menor, de forma que se vaya cribando el registro que está generando el error. Aquí tienes un ejemplo de esta última aproximación para resolver el problema: http://bifase.blogspot.com.es/2010/11/blog-post.html

      Saludos.

  2. hay alguna forma de limpiar los items de una lista para después insertar registro de una tabla, ya que me manda un error pues los datos que envio a la lista se duplican al no coincidir el ID de mi tabla con el ID que se genera en la lista por cada elemento nuevo

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like
Leer más

Introducción a Power Query

En esta entrada repasamos la definición de ETL, presentamos SQL Server Integration Services en el contexto de BI corporativo para dar paso a Power Query como solución de BI personal.