SSIS – Uso de Condicionales en componentes Derived Columns

1 comentarios

Quizás se han preguntado alguna vez si es posible el uso de condicionales dentro de un componente de un Data Flow para de esta manera setear el valor de un campo de destino si se cumple determinada condición en un dato de origen. Por ejemplo, si el campo Sexo es igual a 1 (sexo = 1) en el destino debe almacenarse el Valor “Mascuilno”, caso contrario, debe almacenarse el valor “Femenino”. La sintaxis sería la siguiente:
([sexo] == ”1”) ? “Masculino” : “Femenino”
Esta sintaxis puede aplicarse en un componente Derived Column como se puede ver en el siguiente ejemplo. Lo primero que haremos es crear un fichero como el siguiente:


Luego crearemos un nuevo proyecto de Integration Services en SQL Server Business Intelligence Development Studio con el nombre de “Conditional”.
Crearemos las conexiones de origen y destino respectivas como se ven en las siguientes imágenes.






Conexión de Origen – Flat File


Conexión de Destino – Flat File


Insertamos en el Control Flow un Data Flow Task la que llamaremos “Conditional Data Flow task” y dentro de este último insertaremos un Flat File Source, un Derived Column y en Flat File Destination y los relacionaremos como se muestra en la figura siguiente:


En el componente Derived Column pondremos el siguiente código que permitirá realizar la determinación del Sexo del Cliente que se está procesando.


Posteriormente, en el Flat File Destination debemos cambiar el mapeo de campos como se ve en la siguiente figura, para que de esta manera la nueva columna derivada que hemos creado se vincule con la columna “sexo” del fichero de destino.


El resultado del proceso será el siguiente un archivo llamado Cliente_Destino.txt con el siguiente contenido:

SSIS - Uso de Precedence Constraint para direccionar el Flujo de datos

8 comentarios

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.

Abrir archivos con programa por default (.Net 2.0)

0 comentarios

He retornado, pero esta vez no para escribir sobre SSIS sino sobre una funcionalidad muy sencilla pero no menos interesante del Framework .Net 2.0. Se trata del método Process.Start(), útil para abrir los archivos de cualquier tipo con la aplicación que le corresponde según su extensión. Por ejemplo, si tenemos un archivo con extensión “.doc” o “.docx”, el método se encargará de abrir el archivo con Microsoft Word en la versión que tengamos instalada en nuestra PC. Aquí les pongo un ejemplo tanto para VB como para C#.



Cómo podemos deducir de éste simple código, declaramos que utilizaremos los componentes de System.Diagnostics, luego creamos una proceso llamado “pr”, le asignamos el archivo que deseamos abrir y luego le decimos que comience el proceso. El resultado de este código es que se abrirá el archivo seleccionado con Microsoft Word inmediatamente después de ejecutarse la sentencia pr.Start().