SSIS/Sql Server/Visual Studio 2019.
Eu tenho um grande arquivo csv que tem muitos dados duvidosos. Uma coisa que eu queria fazer era pelo menos tentar reconhecer as linhas sequenciais que são as mesmas e expulsar as duplicatas. Por "mesmo" eu queria verificar 2 valores de coluna específicos - Nome e Empresa.
Eu tenho um fluxo que parece que deve funcionar (dado que este é meu primeiro pacote SSIS e experiência limitada), mas não captura as duplicatas sequenciais. Não sei se é porque não estou entendendo a sintaxe da expressão Conditional Split, a maneira como um Script Component funciona ou quando/como as alterações de variável de pacote devem entrar em vigor nos componentes de script. Ninguém está lançando erros, mas as linhas do arquivo que são duplicatas sequenciais não estão sendo enviadas para o canal de "rejeições".
Eu criei duas variáveis de pacote (lastName e lastCompany), inicializadas com "".
O fluxo tem uma fonte de arquivo Simples lendo e, em seguida, uma Divisão Condicional com, entre outras cláusulas na expressão,
... && !(Name == @[User::lastName] && Company == @[User::lastCompany]) &&
A ideia era que qualquer coisa que correspondesse a todas as cláusulas iria para o caminho de "sucesso" e as linhas que falhassem em qualquer uma dessas verificações iriam para o fluxo de "rejeições".
A próxima coisa no fluxo de "sucesso" é um Script Component que faz alguma normalização de dados e (pelo menos tenta) atualizar as variáveis do pacote. Encontrei outro artigo de baixo para o modelo.
public override void PostExecute()
{
base.PostExecute();
// I've been trying to debug this and get some output on the VS output window but so far nothing has worked.
// Trace is not showing up in DbgView, FireInformation and FireWarning didn't show up in any of the windows in VS
Trace.WriteLine($"Starting: [{Variables.lastName}|{Variables.lastCompany}], Ending: [{lastName}|{lastCompany}]");
Variables.lastCompany = lastCompany;
Variables.lastName = lastName;
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
...
lastName = Row.Name;
lastCompany = Row.Company;
}
O que estou perdendo
- A persistência de variáveis de pacote e atualizações de componentes de script?
- Comportamento da expressão de divisão condicional?
Quer dizer, parece que deveria funcionar para mim, mas não é.
Obrigado
Os valores das variáveis SSIS só podem ser modificados na fase
OnPreExecute
deOnPostExecute
execução do pipeline. Durante a execução, eles são estáticos.Você pode verificar esse comportamento adicionando uma coluna ao fluxo de dados com uma tarefa de coluna derivada e usar adicionar sua variável
@[User::lastName]
após a tarefa de script. Você verá que o valor nunca muda entre a primeira e a última linha.Portanto, você tem um erro lógico com este snippet
Então, o que você faz?
O maior desafio, claro, é que você tem um arquivo de 330 milhões de linhas.
Se nos preocupamos apenas com duplicatas sequenciais, uma tarefa de script conforme você projetou está correta, exceto tentar atribuir às variáveis do SSIS. Em vez disso, você precisará adicionar colunas ao fluxo de dados para que sua divisão condicional subsequente possa fazer uma escolha lógica. Para um trabalho normal, eu ficaria bem em adicionar um lastName e lastCompany ao buffer de dados. No entanto, como você trabalhará em grandes conjuntos de dados, precisará lutar por cada fragmento de memória que conseguir. Em vez disso, eu executaria a lógica de comparação em sua tarefa de script e simplesmente emitiria um booleano indicando se essa linha é uma duplicata da linha anterior.
Eu teria uma Tarefa de Script, agindo como uma transformação após sua fonte de arquivo. Levaria como colunas de entrada somente leitura
Company
eName
adicionaria uma nova coluna à saída chamadaIsDuplicate
Agora você pode simplificar sua Divisão Condicional para a condição de nossa coluna
IsDuplicate
. Eu encaminhei todas as linhas correspondentes para uma saída chamada "Duplicação sequencial" e meu caminho padrão é chamado de "Primeira linha ou linhas não duplicadas". Mais uma vez, tento ser o mais óbvio com minha intenção para que eu possa colocar meu cérebro de volta no jogo quando tiver que mantê-lo.Isso resulta em meu fluxo de dados parecendo