Tarea SSIS para importación de recuento de columna inconsistente?

Problema.

Recibo regularmente un archivo de feed de diferentes proveedores. Aunque los nombres de las columnas son consistentes, el problema surge cuando algunos proveedores envían archivos de texto con más o menos columnas en el archivo de alimentación.

Además, la disposición de estos archivos es inconsistente.

Además de la tarea de flujo de datos dynamic proporcionada por Cozy Roc, existe otra forma en que podría importar estos archivos. No soy un gurú de C #, pero me dirigen a torwards utilizando una tarea de flujo de datos “Script Task” o “Script Component”.

Cualquier sugerencia, muestra o dirección será muy apreciada.

http://www.cozyroc.com/ssis/data-flow-task

Algunos foros

http://www.sqlservercentral.com/Forums/Topic525799-148-1.aspx#bm526400

http://www.bidn.com/forums/microsoft-business-intelligence/integration-services/26/dynamic-data-flow

Fuera de mi cabeza, tengo una solución del 50% para ti.

El problema

SSIS realmente se preocupa por los metadatos, por lo que las variaciones tienden a dar lugar a excepciones. DTS fue mucho más indulgente en este sentido. Esa gran necesidad de metadatos coherentes hace uso de la fuente Flat File Source.

Solución basada en consultas

Si el problema es el componente, no lo usemos. Lo que me gusta de este enfoque es que, conceptualmente, es lo mismo que consultar una tabla: el orden de las columnas no importa, ni importa la presencia de columnas adicionales.

Variables

Creé 3 variables, todas de tipo cadena: CurrentFileName, InputFolder y Query.

  • InputFolder está conectado a la carpeta de origen. En mi ejemplo, es C:\ssisdata\Kipreal
  • CurrentFileName es el nombre de un archivo. Durante el tiempo de diseño, fue input5columns.csv pero eso cambiará en el tiempo de ejecución.
  • Query es una expresión "SELECT col1, col2, col3, col4, col5 FROM " + @[User::CurrentFilename]

ventana de variables

Gerente de conexión

Configure una conexión al archivo de entrada usando el controlador JET OLEDB . Después de crearlo como se describe en el artículo vinculado, lo renombré a FileOLEDB y establecí una expresión en ConnectionManager de "Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited;\";"

Flujo de control

Mi flujo de control se parece a una tarea de flujo de datos anidada en un enumerador de archivos Foreach

flujo de control

Enumerador de archivos Foreach

El enumerador de Mi archivo Foreach está configurado para operar en archivos. Puse una expresión en el Directorio para @[User::InputFolder] Observe que en este punto, si el valor de esa carpeta necesita cambiarse, se actualizará correctamente tanto en Connection Manager como en el enumerador de archivos. En “Recuperar nombre de archivo”, en lugar de “Totalmente calificado”, elija “Nombre y extensión”.

Enumerador de archivos Foreach - pestaña Colección

En la pestaña Asignaciones de variables, asigne el valor a nuestra variable @[User::CurrentFileName]

Enumerador de archivos Foreach - pestaña Asignaciones de variables

En este punto, cada iteración del ciclo cambiará el valor de @[User::Query para reflejar el nombre del archivo actual.

Flujo de datos

Esta es realmente la pieza más fácil. Use una fuente OLE DB y conéctela como se indica.

Flujo de datos

Utilice el administrador de conexión FileOLEDB y cambie el modo de Acceso a datos a “Comando SQL desde la variable”. Use la variable @[User::Query] allí, haga clic en OK y estará listo para trabajar. fuente de archivo oledb

Data de muestra

Creé dos archivos de muestra input5columns.csv y input7columns.csv Todas las columnas de 5 están en 7, pero 7 las tiene en un orden diferente (col2 es la posición ordinal 2 y 6). Negué todos los valores en 7 para que sea fácilmente evidente qué archivo está siendo operado.

 col1,col3,col2,col5,col4 1,3,2,5,4 1111,3333,2222,5555,4444 11,33,22,55,44 111,333,222,555,444 

y

 col1,col3,col7,col5,col4,col6,col2 -1111,-3333,-7777,-5555,-4444,-6666,-2222 -111,-333,-777,-555,-444,-666,-222 -1,-3,-7,-5,-4,-6,-2 -11,-33,-77,-55,-44,-666,-222 

Ejecutando los resultados del paquete en estas dos capturas de pantalla

Archivo de 5 columnasArchivo de 7 columnas

Lo que falta

No sé de una manera de decir al enfoque basado en consultas que está bien si una columna no existe. Si hay una clave única, supongo que podría definir su consulta para tener solo las columnas que deben estar allí y luego realizar búsquedas contra el archivo para intentar obtener las columnas que deberían estar allí y no fallar la búsqueda si la columna no lo hace t existe. Bastante kludgey sin embargo.

Nuestra solución. Usamos paquetes para padres y niños. En el paquete padre, tomamos los archivos individuales del cliente y los transformamos en nuestros archivos de formato estándar, luego llamamos al paquete secundario para procesar la importación estándar utilizando el archivo que creamos. Esto solo funciona si el cliente es coherente en lo que envían, si intentan cambiar su formato de acuerdo con lo que acordaron enviarnos, devolveremos el archivo.