En éste, mi 3er Post sobre Integration Services voy a mostrarles un ejemplo de cómo desviar el flujo de datos que queremos importar según se cumplan ciertas condiciones. El ejemplo que veremos a continuación, si bien es muy simple, nos servirá para ilustrar una forma de razonamiento muy útil para diversas situaciones.
Supongamos que tenemos una empresa en la que los clientes pueden ser Nacionales e Internacionales. El proceso que debemos realizar debe tomar los datos desde 2 ficheros “.txt” los cuales poseen nombres que los diferencian si se tratan de clientes Nacionales o Extranjeros. El formato del nombre de los ficheros para clientes nacionales es ddmmaaaaNac.txt y para los Internacionales es ddmmaaaaInt.txt y estructuralmente la diferencia es que éstos últimos poseen una columna más denominada “Pais” y por éste motivo deben procesarse por separado, de lo contrario se produciría un error.
Los pasos a seguir en la construcción del ejemplo serán:
1. Creación de Ficheros Origen y Tabla de destino de Datos
2. Creación del Proceso SSIS
3. Ejecución del proceso y análisis de resultados
1. Creación de Ficheros Origen y Tabla de destino de Datos
Para comenzar nuestro ejemplo, debemos crear 4 ficheros “.txt” (ver imagen) en los cuales el separador de columnas es el “tab” y el de filas el “Enter” ({CR}{LF})
Una vez creados estos 4 ficheros con sus respectivos nombres, estructuras y contenidos pasemos a la creación de la tabla destino en SQL Server.
El nombre de la tabla será TablaClientes en la BD Examples y su estructura será la siguiente:
2. Creación del Proceso SSIS
Abriremos el SQL Server Business Intelligence Development Studio donde de crearemos un nuevo proyecto de Integration Services, como nombre le pondremos “Condicional”.
Una vez situados en el Control Flow del Package crearemos 2 variables, la primera se llamará varFileName que contendrá el nombre del fichero que se está procesando en un momento determinado y la variable varFilenationality, la cual albergará los valores “Nac” o “Int” según sea la terminación del archivo procesado. Ambas variables serán de tipo String.
Posteriormente agregaremos las conexiones con los ficheros de Origen y la BD de destino de Datos. Tendremos 2 Flat File Connection, una para los Clientes nacionales y otra para los clientes internacionales, y una OLE DB Connection que se conectará a la BD Examples.
Para las Flat Connections deberemos seleccionar el primer fichero “txt” que creamos con anterioridad según se trate de clientes Nacionales o internacionales, es decir, para la conexión “Clientes Nacionales – Origen” debemos seleccionar como File Name 15102007Nac.txt y para “Clientes Internacionales – Origen” debemos seleccionar como File Name 15102007Int.txt
Además, para estas Flat Connections debemos modificar su propiedad Expressions y colocar como connectionString la variable varFileName. Esto permite que a medida que el foreach recorre los ficheros del directorio, los orígenes de datos obtengan sus datos de los ficheros correspondientes.
Luego, sobre la superficie del Control Flow agregaremos un componente Foreach en el cual definiremos el path que contiene los ficheros y el tipo de ficheros a importar, en nuestro caso “*.txt”
En la opción Variable Mappings del Foreach asignaremos la variable varFileName.
A continuación agregaremos dentro del Foreach un Script Task con el cual podremos determinar si el fichero procesado por el foreach se trata de clientes Nacionales o Internacionales. Renombraremos el script task como “Obtener Ambito Cliente” y lo editaremos. En la opción Script, haremos click en el botón Design Script donde agregaremos el siguiente código:
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Public Class ScriptMain
Public Sub Main()
Dim vars As Variables
Dim FileNationality As String
Dim varsNationality As Variables
'asignamos a la variable local "vars" el contenido de la variable varFileName
'que obtiene el nombre del fichero en el Foreach
Dts.VariableDispenser.LockOneForRead("User::varFileName", vars)
'Procesamos la variable varFileName para obtener el ámbito del fichero txt
FileNationality = vars("varFileName").Value.ToString.Substring(vars("varFileName").Value.ToString.Length - 7, 3)
'instanciamos y asignamos a la variable varFileNationality el ámbito obtenido
Dts.VariableDispenser.LockOneForWrite("varFileNationality", varsNationality)
varsNationality("varFileNationality").Value = FileNationality
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
Resumiendo el código, vemos que obtenemos el nombre del fichero que estamos procesando en este momento procesando la variable varFileName, de la cual extraemos el ámbito (Nac o Int) y lo asignamos a la variable varFileNationality. Ésta variable será la que utilizaremos para desviar el flujo de datos hacia un Data Flow u otro más adelante.
El siguiente paso consiste en crear 2 Data Flow, uno llamado “Clientes Nacionales Data Flow Task” y el otro “Clientes Internacionales Data Flow Task”, donde el primero se encargará de importar en la tabla TablaClientes de la BD Examples los datos relativos a los clientes Nacionales y el segundo, los datos de los clientes Internacionales.
Arrastramos sendas flechas desde el Script hasta los Data Flow recientemente creados y el siguiente paso será editar los Precedence Constraint haciendo doble click sobre las mencionadas flechas que unen el Script con los Data Flow.
Editemos el Precedence Constraint que une el Script con el Clientes Nacionales Data Flow Task. Allí debemos cambiar la Evaluation operation a Expression y dentro del campo homónimo escribir:
@[User::varFileNationality] == "Nac"
Damos OK y repetimos la operación para el Precedence Constraint que une el script con el el Clientes Internacionales Data Flow Task, imitamos la configuración anterior pero reemplazando la Expression por la siguiente:
@[User::varFileNationality] == "Int"
El Control Flow quedará de la siguiente manera:
Con esto hemos finalizado el Control Flow, por lo que debemos realizar la funcionalidad de los Data Flow Clientes Nacionales Data Flow Task y Clientes Internacionales Data Flow Task. En ambos debemos agregar un Flat File Source en donde utilizarán las conexiones “Clientes Nacionales – Origen” y “Clientes Internacionales – Origen” respectivamente. Posteriormente debemos agregar un OLE DB Destination que utilizará la conexión ““localhost.Examples” antes creada.
Luego de unir ambos componentes arrastrando la flecha verde del Flat File Source al OLE DB Destination, debemos realizar el mapeo de los campos en éste último.
Cómo podemos ver ambos Data Flow son muy similares, excepto que en el de los clientes Nacionales no disponemos de la columna “Pais” y por lo tanto no podemos mapearla a la Tabla de la BD.
3. Ejecución del proceso y análisis de resultados
El siguiente y último paso será ejecutar el proceso. Si nos paramos sobre el Control Flow de modo tal de ver el Foreach y todo su contenido y ejecutamos el proceso (Presionando F5) veremos cómo según sea el fichero que se está procesando correspondiente a clientes Nacionales o Internacionales, la ejecución se destinará a uno u otro Data Flow de acuerdo a que condición cumpla la variable varFilenationality obtenida.
Si analizamos los datos de la tabla TablaClientes podemos ver que se han importado correctamente los datos y la diferencia entre los clientes Nacionales e Internacionales es que estos últimos poseen un País, mientras que los nacionales tienen el valor NULL en ese campo.
Espero les haya sido de utilidad mi ejemplo y no duden en escribir comentarios ante cualquier duda o inquietud.