Tarefa SSIS para importação inconsistente de contagem de colunas?

Problema.

Recebo regularmente arquivos de feed de diferentes fornecedores. Embora os nomes das colunas sejam consistentes, o problema surge quando alguns fornecedores enviam arquivos de texto com mais ou menos colunas no arquivo de feed.

Além disso, a organização desses arquivos é inconsistente.

Além da tarefa de stream de dados dynamics fornecida pela Cozy Roc, há outra maneira de importar esses arquivos. Eu não sou um c # guru, mas eu sou orientado torwards usando um stream de controle “Script Task” ou tarefa de stream de dados “Script Component”.

Qualquer sugestão, amostra ou direção será muito apreciada.

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

Alguns fóruns

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

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

No topo da minha cabeça, eu tenho uma solução de 50% para você.

O problema

O SSIS realmente se importa com os metadados, portanto, variações nele tendem a resultar em exceções. DTS foi muito mais indulgente nesse sentido. Essa grande necessidade de metadados consistentes faz uso do problema da Fonte de Arquivo Simples.

Solução baseada em consulta

Se o problema é o componente, não vamos usá-lo. O que eu gosto nessa abordagem é que, conceitualmente, é o mesmo que consultar uma tabela – a ordem das colunas não importa nem a presença de colunas extras é importante.

Variáveis

Eu criei 3 variables, todas do tipo string: CurrentFileName, InputFolder e Query.

  • InputFolder é ligado à pasta de origem. No meu exemplo, é C:\ssisdata\Kipreal
  • CurrentFileName é o nome de um arquivo. Durante o tempo de design, foi input5columns.csv mas isso será alterado no tempo de execução.
  • Query é uma expressão "SELECT col1, col2, col3, col4, col5 FROM " + @[User::CurrentFilename]

janela de variáveis

Gerenciador de conexões

Configure uma conexão com o arquivo de input usando o driver JET OLEDB . Depois de criá-lo conforme descrito no artigo vinculado, renomei-o como FileOLEDB e defini uma expressão no ConnectionManager de "Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited;\";"

Controle de stream

Meu stream de controle se parece com uma tarefa de stream de dados aninhada em um enumerador de arquivo Foreach

controle de fluxo

Enumerador de Arquivos Foreach

Meu Enumerador de Arquivos Foreach está configurado para operar em arquivos. Eu coloquei uma expressão no diretório para @[User::InputFolder] Observe que, neste ponto, se o valor dessa pasta precisa ser alterado, ela será atualizada corretamente no Connection Manager e no enumerador de arquivos. Em “Recuperar nome do arquivo”, em vez do padrão “Totalmente qualificado”, escolha “Nome e extensão”

Enfileirador de Arquivos Foreach - guia Coleção

Na aba Variable Mappings, atribua o valor à nossa variável @[User::CurrentFileName]

Enfileirador de Arquivos Foreach - guia Mapeamentos Variáveis

Nesse ponto, cada iteração do loop alterará o valor de @[User::Query para refletir o nome do arquivo atual.

Fluxo de dados

Esta é realmente a parte mais fácil. Use uma fonte OLE DB e conecte-a conforme indicado.

Fluxo de dados

Use o gerenciador de conexões FileOLEDB e altere o modo Acesso a Dados para “Comando SQL da variável”. Use a variável @[User::Query] , clique em OK e você estará pronto para trabalhar. fonte de arquivo oledb

Dados de amostra

Criei dois arquivos de amostra input5columns.csv e input7columns.csv Todas as colunas de 5 estão em 7, mas 7 as têm em uma ordem diferente (col2 é a posição ordinal 2 e 6). Eu neguei todos os valores em 7 para tornar evidente qual arquivo está sendo 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 

e

 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 

Executar os resultados do pacote nessas duas capturas de canvas

Arquivo de 5 colunasArquivo de coluna 7

O que está a faltar

Eu não sei de uma maneira de dizer à abordagem baseada em consulta que não há problema se uma coluna não existir. Se houver uma chave única, suponho que você poderia definir sua consulta para ter apenas as colunas que devem estar lá e, em seguida, executar pesquisas no arquivo para tentar obter as colunas que deveriam estar lá e não falhar na pesquisa se a coluna não existir existe. Muito kludgey embora.

Nossa solução. Nós usamos pacotes filho pai. No pacakge pai, pegamos os arquivos individuais do cliente e os transformamos em nossos arquivos de formato padrão, em seguida, chamamos o pacote filho para processar a importação padrão usando o arquivo que criamos. Isso só funciona se o cliente é consistente no que eles enviam, no entanto, se eles tentarem mudar seu formato do que eles concordaram em nos enviar, nós retornamos o arquivo.