AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 305801
Accepted
user1664043
user1664043
Asked: 2022-01-08 15:22:12 +0800 CST2022-01-08 15:22:12 +0800 CST 2022-01-08 15:22:12 +0800 CST

SSIS detectando duplicatas sequenciais

  • 772

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

  1. A persistência de variáveis ​​de pacote e atualizações de componentes de script?
  2. Comportamento da expressão de divisão condicional?

Quer dizer, parece que deveria funcionar para mim, mas não é.

Obrigado

sql-server ssis
  • 1 1 respostas
  • 95 Views

1 respostas

  • Voted
  1. Best Answer
    billinkc
    2022-01-09T09:59:32+08:002022-01-09T09:59:32+08:00

    Os valores das variáveis ​​SSIS só podem ser modificados na fase OnPreExecutede OnPostExecuteexecuçã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

    (Name == @[User::lastName] && Company == @[User::lastCompany])
    

    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 Companye Nameadicionaria uma nova coluna à saída chamadaIsDuplicate

    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
        // member variables to keep track of previous row data
        private string lastName;
        private string lastCompany;
    
        public override void PreExecute()
        {
            base.PreExecute();
            // initialize our variables
            this.lastCompany = "";
            this.lastName = "";
        }
    
        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
            // Encapsulate the logic from the Derived Column comparison here 
            //
            // Are the two elements the same?
            // Do we have to worry about nulls here? Assuming not
            // Also assuming a case sensitive match is desired
            if (Row.Company == this.lastCompany && Row.Name == this.lastName)
            {
                Row.IsDuplicate = true;
            }
            else
            {
                // strictly speaking, this is not required as the default value for a bit if false but I favor explicit behaviour
                Row.IsDuplicate = false;
            }
    
            // Update the member variables to the previous row's data
            this.lastName = Row.Name;
            this.lastCompany = Row.Company;
        }
    }
    

    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.

    insira a descrição da imagem aqui

    Isso resulta em meu fluxo de dados parecendo

    insira a descrição da imagem aqui

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve