miércoles, 30 de mayo de 2012

SSIS: Obtener metadatos de ficheros

 

Introducción

Muchas veces es necesario comprobar algún metadato de un fichero antes de procesarlo. Supongamos que tenemos un paquete ETL que recoge un fichero con un volumen de datos importante, pongamos 100 millones de filas ( si, a veces pasa :) ). El contenido del fichero se genera cada cierto tiempo, pero su nombre nunca cambia. Cabe la posibilidad de obtener todo el contenido para compararlo contra el destino de datos, pero es una tarea que podemos (y debemos) evitar.

En este caso vamos a obtener la fecha de modificación de un fichero para determinar si es necesario procesarlo.

Obteniendo el metadato

Tenemos en un directorio un fichero llamado ventas.csv y disponemos de una tabla en la que vamos registrando la última fecha de modificación de forma que vamos a comparar este dato con el que tiene actualmente el fichero.

La estructura de la tabla es la siguiente:

CREATE TABLE [dbo].[FilesToProcess](
[Id] [int] NOT NULL,
[FileFullName] [varchar](255) NOT NULL,
[LastModifiedDate] [datetime] NOT NULL,
[ProcessDate] AS (getdate())
)
 
image

Para empezar, nos creamos tres variables de SSIS: vFilesFullName, vFileModifiedDate y vLastModifiedDate


image


Para obtener última fecha de modificación, añadimos un Execute TSQL Task al Control Flow y realizamos una consulta que nos devuelva el nombre del fichero a procesar y la última fecha de modificación que registramos:

SELECT [FileFullName], [LastModifiedDate]
FROM [dbo].[FilesToProcess]

En la sección General establecemos la opción ResultSet a Single Row


En la sección Result Set, mapeamos el resultado a las variables:


image


Añadimos un Script Task y lo conectamos a la salida de la tarea anterior. Editamos su configuración y establecemos las variables que va a utilizar. Como variables de lectura añadimos vFileFullName y vLastModifiedName y como variable escribible seleccionamos vFileModifiedName:


image


Lo siguiente es añadir el código al componente (personalmente prefiero C#)

public void Main()
{
// TODO: Add your code here
try
{
System.IO.FileInfo mFileInfo = new System.IO.FileInfo(Dts.Variables["vFileFullName"].Value.ToString());

if (mFileInfo != null)
{
Dts.Variables["vFileModifiedDate"].Value = mFileInfo.LastWriteTime;
Dts.TaskResult = (int)ScriptResults.Success;
}
else
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
catch(Exception ex)
{
Dts.Events.FireError(-1, ex.Source, ex.Message,string.Empty , 0);
}

}

Como veis, utilizamos la clase System.IO.FileInfo para obtener la fecha de modificación que actualmente tiene el fichero.


Lo siguiente, es añadir un DataFlow para procesar el fichero. Conectamos el Script Task con el Data Flow  y modificamos la restricción de precedencia (precedence constraint) para añadir la expresión:

@vFileModifiedDate!=@vLastModifiedDate

image


El aspecto final de este diseño debería ser el de la siguiente imagen:


image


Resumen


A través de la inclusión de código en Script tasks y Script Component podemos proveer a nuestros paquetes ETL de Integration Services. A través de este ejemplo hemos visto como solucionar un requisito que puede ser habitual encontrarse.


Si queréis descargaros el paquete de ejemplo dejadme un comentario, estaré encantado de compartirlo con vosotros


Guiño

Entradas populares