Partilhar via


Analisando formatos de arquivo de texto fora do padrão com o componente Script

Quando seus dados de origem são dispostos em um formato não padrão, talvez seja mais conveniente consolidar toda a sua lógica de análise em um único script do que reunir várias transformações Integration Services para atingir o mesmo resultado.

Exemplo 1: Analisando registros delimitados por linha

Exemplo 2: Dividindo registros pai e filho

ObservaçãoObservação

Se desejar criar um componente que possa ser reutilizado mais facilmente em várias tarefas de fluxo de dados e em vários pacotes, procure utilizar o código deste exemplo de componente Script como o ponto inicial de um componente de fluxo de dados personalizado. Para obter mais informações, consulte Desenvolvendo um componente de fluxo de dados personalizado.

Exemplo 1: Analisando registros delimitados por linha

Este exemplo mostra como utilizar um arquivo de texto em que cada coluna de dados aparece em uma linha separada e analisá-lo em uma tabela de destino usando o componente Script.

Para obter mais informações sobre como configurar o componente Script para uso como uma transformação no fluxo de dados, consulte Criando uma transformação síncrona com o componente Script e Criando uma transformação assíncrona com o componente Script.

Para configurar esse exemplo de componente Script

  1. Crie e salve um arquivo de texto nomeado rowdelimiteddata.txt contendo os seguintes dados de origem:

    FirstName: Nancy
    LastName: Davolio
    Title: Sales Representative
    City: Seattle
    StateProvince: WA
    
    FirstName: Andrew
    LastName: Fuller
    Title: Vice President, Sales
    City: Tacoma
    StateProvince: WA
    
    FirstName: Steven
    LastName: Buchanan
    Title: Sales Manager
    City: London
    StateProvince:
    
  2. Abra o Management Studio e conecte-se a uma instância do SQL Server.

  3. Selecione um banco de dados de destino e abra uma nova janela de consulta. Na janela de consulta, execute o seguinte script para criar a tabela de destino:

    create table RowDelimitedData
    (
    FirstName varchar(32),
    LastName varchar(32),
    Title varchar(32),
    City varchar(32),
    StateProvince varchar(32)
    )
    
  4. Abra o BI Development Studio e crie um novo pacote de Integration Services nomeado ParseRowDelim.dtsx.

  5. Adicione um gerenciador de conexões de arquivos simples ao pacote, nomeie-o como RowDelimitedData e configure-o para conectá-lo ao arquivo rowdelimiteddata.txt criado em uma etapa anterior.

  6. Adicione um gerenciador de conexões OLE DB ao pacote e configure-o para conectá-lo à instância do SQL Server e ao banco de dados em que você criou a tabela de destino.

  7. Adicione uma tarefa de Fluxo de Dados ao pacote e clique na guia Fluxo de Dados do Designer SSIS.

  8. Adicione uma Fonte de Arquivo Simples ao fluxo de dados e configure-a para usar o gerenciador de conexões do RowDelimitedData. Na página Colunas do Editor de Fonte de Arquivo Simples, selecione a única coluna externa disponível.

  9. Adicione um Componente Script ao fluxo de dados e configure-o como uma transformação. Conecte a saída da Fonte de Arquivo Simples ao Componente Script.

  10. Clique duas vezes no componente Script para exibir o Editor de Transformação Scripts.

  11. Na página Colunas de Entrada do Editor de Transformação Scripts, selecione a única coluna de entrada disponível.

  12. Na página Entradas e Saídas do Editor de Transformação Scripts, selecione Saída 0 e defina seu SynchronousInputID como 0. Crie 5 colunas de saída, todas com tipo cadeia de caracteres [DT_STR] com comprimento de 32:

    • FirstName

    • LastName

    • Title

    • City

    • StateProvince

  13. Na página Script do Editor de Transformação Scripts, clique em Editar Script e digite o código mostrado na classe ScriptMaindo exemplo. Feche o ambiente de desenvolvimento de scripts e o Editor de Transformação Scripts.

  14. Adicione um Destino de SQL Server ao fluxo de dados. Configure-o para usar o gerenciador de conexões do OLE DB e a tabela RowDelimitedData. Conecte a saída do Componente Script a este destino.

  15. Execute o pacote. Depois da conclusão do pacote, examine os registros na tabela de destino SQL Server.

    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

        Dim columnName As String
        Dim columnValue As String

        ' Check for an empty row.
        If Row.Column0.Trim.Length > 0 Then
            columnName = Row.Column0.Substring(0, Row.Column0.IndexOf(":"))
            ' Check for an empty value after the colon.
            If Row.Column0.Substring(Row.Column0.IndexOf(":")).TrimEnd.Length > 1 Then
                ' Extract the column value from after the colon and space.
                columnValue = Row.Column0.Substring(Row.Column0.IndexOf(":") + 2)
                Select Case columnName
                    Case "FirstName"
                        ' The FirstName value indicates a new record.
                        Me.Output0Buffer.AddRow()
                        Me.Output0Buffer.FirstName = columnValue
                    Case "LastName"
                        Me.Output0Buffer.LastName = columnValue
                    Case "Title"
                        Me.Output0Buffer.Title = columnValue
                    Case "City"
                        Me.Output0Buffer.City = columnValue
                    Case "StateProvince"
                        Me.Output0Buffer.StateProvince = columnValue
                End Select
            End If
        End If

    End Sub
public override void Input0_ProcessInputRow(Input0Buffer Row)
    {

        string columnName;
        string columnValue;

        // Check for an empty row.
        if (Row.Column0.Trim().Length > 0)
        {
            columnName = Row.Column0.Substring(0, Row.Column0.IndexOf(":"));
            // Check for an empty value after the colon.
            if (Row.Column0.Substring(Row.Column0.IndexOf(":")).TrimEnd().Length > 1)
            // Extract the column value from after the colon and space.
            {
                columnValue = Row.Column0.Substring(Row.Column0.IndexOf(":") + 2);
                switch (columnName)
                {
                    case "FirstName":
                        // The FirstName value indicates a new record.
                        this.Output0Buffer.AddRow();
                        this.Output0Buffer.FirstName = columnValue;
                        break;
                    case "LastName":
                        this.Output0Buffer.LastName = columnValue;
                        break;
                    case "Title":
                        this.Output0Buffer.Title = columnValue;
                        break;
                    case "City":
                        this.Output0Buffer.City = columnValue;
                        break;
                    case "StateProvince":
                        this.Output0Buffer.StateProvince = columnValue;
                        break;
                }
            }
        }

    }

Exemplo 2: Dividindo registros pai e filho

Este exemplo mostra como utilizar um arquivo de texto, em que uma linha delimitadora precede uma linha de registro pai, que é seguida de um número indefinido de linhas de registro filho, e analisa-as em tabelas de destino pai e filho, adequadamente normalizadas, através do componente Script. Esse exemplo simples pode ser facilmente adaptado para arquivos de origem que utilizam mais de uma linha ou coluna para cada registro pai e filho, desde que exista uma forma de identificar o início e o fim de cada registro.

Observação sobre cuidadosCuidado

Esse exemplo é utilizado apenas para fins de demonstração. Se você executar o exemplo mais de uma vez, ele inserirá valores de chave duplicados na tabela de destino.

Para obter mais informações sobre como configurar o componente Script para uso como uma transformação no fluxo de dados, consulte Criando uma transformação síncrona com o componente Script e Criando uma transformação assíncrona com o componente Script.

Para configurar esse exemplo de componente Script

  1. Crie e salve um arquivo de texto nomeado parentchilddata.txt contendo os seguintes dados de origem:

******** PARENT 1 DATA child 1 data child 2 data child 3 data child 4 data ******** PARENT 2 DATA child 5 data child 6 data child 7 data child 8 data ********

  1. Abra o SQL Server Management Studio e conecte-se a uma instância do SQL Server.

  2. Selecione um banco de dados de destino e abra uma nova janela de consulta. Na janela de consulta, execute o seguinte script para criar as tabelas de destino:

    CREATE TABLE [dbo].[Parents](
    [ParentID] [int] NOT NULL,
    [ParentRecord] [varchar](32) NOT NULL,
     CONSTRAINT [PK_Parents] PRIMARY KEY CLUSTERED 
    ([ParentID] ASC)
    )
    GO
    CREATE TABLE [dbo].[Children](
    [ChildID] [int] NOT NULL,
    [ParentID] [int] NOT NULL,
    [ChildRecord] [varchar](32) NOT NULL,
     CONSTRAINT [PK_Children] PRIMARY KEY CLUSTERED 
    ([ChildID] ASC)
    )
    GO
    ALTER TABLE [dbo].[Children] ADD CONSTRAINT [FK_Children_Parents] FOREIGN KEY([ParentID])
    REFERENCES [dbo].[Parents] ([ParentID])
    
  3. Abra o Business Intelligence Development Studio e crie um novo pacote Integration Services nomeado SplitParentChild.dtsx.

  4. Adicione um gerenciador de conexões de arquivos simples ao pacote, nomeie-o como ParentChildData e configure-o para conectá-lo ao arquivo parentchilddata.txt criado em uma etapa anterior.

  5. Adicione um gerenciador de conexões OLE DB ao pacote e configure-o para conectar-se à instância do SQL Server e ao banco de dados em que você criou as tabelas de destino.

  6. Adicione uma tarefa de Fluxo de Dados ao pacote e clique na guia Fluxo de Dados do Designer SSIS.

  7. Adicione uma Fonte de Arquivo Simples ao fluxo de dados e configure-a para usar o gerenciador de conexões do ParentChildData. Na página Colunas do Editor de Fonte de Arquivo Simples, selecione a única coluna externa disponível.

  8. Adicione um Componente Script ao fluxo de dados e configure-o como uma transformação. Conecte a saída da Fonte de Arquivo Simples ao Componente Script.

  9. Clique duas vezes no componente Script para exibir o Editor de Transformação Scripts.

  10. Na página Colunas de Entrada do Editor de Transformação Scripts, selecione a única coluna de entrada disponível.

  11. Na página Entradas e Saídas do Editor de Transformação Scripts, selecione Saída 0, renomeie-a como ParentRecords e defina seu SynchronousInputID como Nenhum. Crie 2 colunas de saída:

    • ParentID (a chave primária), de tipo inteiro assinado de quatro bytes [DT_I4]

    • ParentRecord, de cadeia de caracteres de tipo [DT_STR] com comprimento de 32.

  12. Crie uma segunda saída e nomeie-a como ChildRecords. O SynchronousInputID da nova saída já está definido como Nenhum. Crie 3 colunas de saída:

    • ChildID (a chave primária), de tipo inteiro assinado de quatro bytes [DT_I4]

    • ParentID (a chave estrangeira), também de tipo inteiro assinado de quatro bytes [DT_I4]

    • ChildRecord, de cadeia de caracteres de tipo [DT_STR] com comprimento de 50

  13. Na página Script do Editor de Transformação Scripts, clique em Editar Script. Na classe ScriptMain, digite o código mostrado no exemplo. Feche o ambiente de desenvolvimento de scripts e o Editor de Transformação Scripts.

  14. Adicione um Destino de SQL Server ao fluxo de dados. Conecte a saída de ParentRecords do Componente Script a esse destino. Configure-o para usar o gerenciador de conexões OLE DB e a tabela Pais.

  15. Adicione outro Destino de SQL Server ao fluxo de dados. Conecte a saída ChildRecords do Componente Script a esse destino. Configure-o para usar o gerenciador de conexões OLE DB e a tabela Filhos.

  16. Execute o pacote. Depois da conclusão do pacote, examine os registros pai e filho nas duas tabelas de destino do SQL Server.

    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

        Static nextRowIsParent As Boolean = False
        Static parentCounter As Integer = 0
        Static childCounter As Integer = 0

        ' If current row starts with separator characters,
        '  then following row contains new parent record.
        If Row.Column0.StartsWith("***") Then
            nextRowIsParent = True
        Else
            If nextRowIsParent Then
                ' Current row contains parent record.
                parentCounter += 1
                Me.ParentRecordsBuffer.AddRow()
                Me.ParentRecordsBuffer.ParentID = parentCounter
                Me.ParentRecordsBuffer.ParentRecord = Row.Column0
                nextRowIsParent = False
            Else
                ' Current row contains child record.
                childCounter += 1
                Me.ChildRecordsBuffer.AddRow()
                Me.ChildRecordsBuffer.ChildID = childCounter
                Me.ChildRecordsBuffer.ParentID = parentCounter
                Me.ChildRecordsBuffer.ChildRecord = Row.Column0
            End If
        End If

    End Sub
public override void Input0_ProcessInputRow(Input0Buffer Row)
    {

    int static_Input0_ProcessInputRow_childCounter = 0;
    int static_Input0_ProcessInputRow_parentCounter = 0;
    bool static_Input0_ProcessInputRow_nextRowIsParent = false;

        // If current row starts with separator characters, 
        // then following row contains new parent record. 
        if (Row.Column0.StartsWith("***"))
        {
            static_Input0_ProcessInputRow_nextRowIsParent = true;
        }
        else
        {
            if (static_Input0_ProcessInputRow_nextRowIsParent)
            {
                // Current row contains parent record. 
                static_Input0_ProcessInputRow_parentCounter += 1;
                this.ParentRecordsBuffer.AddRow();
                this.ParentRecordsBuffer.ParentID = static_Input0_ProcessInputRow_parentCounter;
                this.ParentRecordsBuffer.ParentRecord = Row.Column0;
                static_Input0_ProcessInputRow_nextRowIsParent = false;
            }
            else
            {
                // Current row contains child record. 
                static_Input0_ProcessInputRow_childCounter += 1;
                this.ChildRecordsBuffer.AddRow();
                this.ChildRecordsBuffer.ChildID = static_Input0_ProcessInputRow_childCounter;
                this.ChildRecordsBuffer.ParentID = static_Input0_ProcessInputRow_parentCounter;
                this.ChildRecordsBuffer.ChildRecord = Row.Column0;
            }
        }

    }
Ícone do Integration Services (pequeno) Fique atualizado com o Integration Services

Para obter os mais recentes downloads, artigos, exemplos e vídeos da Microsoft, bem como soluções selecionadas da comunidade, visite a página do Integration Services no MSDN ou TechNet:

Para receber uma notificação automática das atualizações, assine os feeds RSS disponíveis na página.