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.

🙂

 

Víctor M García Sánchez
Últimas entradas de Víctor M García Sánchez (ver todo)