Meu fluxo de trabalho atual é o seguinte:
Uma tarefa 'Executar tarefa SQL' executa um procedimento armazenado que preenche uma tabela.
Depois disso, uma tarefa 'Dataflow Task' faz o seguinte:
2A. Leia cada linha desta tabela por meio de um 'Componente Dataflow' que usa OpenRowset.
2B. Passa isso para outro componente do Dataflow que faz algumas conversões.
2C. Grava os resultados em CSV.
A passagem da Etapa 1 para a Etapa 2A parece redundante, pois a tabela no servidor nunca mais é usada. Gostaria de fazer com que o procedimento armazenado retornasse as linhas que ele gravaria na tabela e que o fluxo as usasse em vez de ler a tabela. Isso é possível?
Na verdade, posso ter complicado demais a solução abaixo. Você não pode simplesmente definir a fonte de dados em seu fluxo de dados
Data access mode = SQL command
eEXEC youProcedure
cederSQL command text
? Se você precisar fornecer parâmetros não estáticos para o procedimento, useData access mode = SQL command from variable
e construa a string SQL em seu fluxo de controle (usando uma tarefa de expressão) antes de chamar o fluxo de dados?(isso pressupõe um gerenciador de conexões OleDB, pode haver pequenas alterações necessárias para outras fontes)
ResultSet = Full result set
.Result Name = 0
para a variável criada acima.Após a execução desta etapa, a variável conterá o conjunto de resultados completo.
Na sua tarefa de fluxo de dados subsequente:
using System.Data;
eusing System.Data.OleDb;
em seus namespaces.CreateNewOutputRows()
método, copie o conjunto de resultados para um DataTable assim:foreach (DataRow r in sprocResult.Rows)
, adicionar uma linha ao fluxo de saída em cada iteração do loop comOutputRowsBuffer.AddRow()
(alterar o nome para corresponder à saída definida acima) e definir valores comOutputRowsBuffer.<columnname> = r["<columnname>"];
ouOutputRowsBuffer.<columnname>_IsNull = true;
RejectedRowsBuffer.SetEndOfRowset();
.Existem algumas variações dessa técnica, principalmente em torno do uso de métodos diferentes para interagir com o ResultSet no código C#.
Isso será ineficiente para grandes conjuntos de dados (tanto em termos de memória usada quanto, em menor grau, de tempo de processamento) porque você está lendo um resultado estático no espaço de memória do SSIS na variável de objeto e, em seguida, copiando-o para o objeto DataTable em C#. Em vez disso, você poderia fazer com que o script de origem interagisse diretamente com o banco de dados (passá-lo ao gerenciador de conexões e fazer com que ele se conectasse e executasse o procedimento) - dessa forma, os dados serão transmitidos do procedimento armazenado para o seu fluxo de dados sem precisar ser armazenados inteiramente no objeto na RAM entre.