Criando uma transformação assíncrona com o componente Script

Você utiliza um componente de transformação no fluxo de dados de um pacote do Integration Services para modificar e analisar dados à medida que eles passam da origem ao destino. Uma transformação com saídas síncronas processa cada linha de entrada que passa pelo componente. Uma transformação com saídas assíncronas pode aguardar para concluir seu processamento depois de receber todas as linhas de entrada, ou ela pode gerar algumas linhas antes de receber todas as linhas de entrada. Esse tópico discute uma transformação assíncrona. Se seu processamento requerer uma transformação síncrona, consulte Criando uma transformação síncrona com o componente Script. Para obter mais informações sobre as diferenças entre componentes síncronos e assíncronos, consulte Compreendendo as transformações síncronas e assíncronas.

Para obter uma visão geral do componente Script, consulte Estendendo o fluxo de dados com o componente Script.

O componente Script e o código de infra-estrutura gerado para você simplificam o processo de desenvolvimento de um componente de fluxo de dados personalizado. Contudo, para compreender o funcionamento do componente Script, talvez seja útil ler as etapas necessárias ao desenvolvimento de um componente de fluxo de dados personalizado, na seção Desenvolvendo um componente de fluxo de dados personalizado, e especialmente Desenvolvendo um componente de transformação personalizado com saídas síncronas.

Guia de Introdução com um componente de transformação assíncrono

Quando você adicionar um componente Script à guia Fluxo de Dados de Designer SSIS, a caixa de diálogo Selecionar Tipo de Componente do Script aparecerá, solicitando que você pré-configure o componente como uma origem, transformação ou destino. Nessa caixa de diálogo, selecione Transformação.

Configurando um componente de transformação assíncrono em modo do design de metadados

Após selecionar a opção para criar um componente de transformação, configure o componente usando o Editor de Transformação Scripts. Para obter mais informações, consulte Configurando o componente Script no Editor de Componentes de Script.

Para selecionar a linguagem de script que o componente Script utilizará, defina a propriedade ScriptLanguage na página Script da caixa de diálogo Editor de Transformação Scripts.

ObservaçãoObservação

Para definir a linguagem de scripts padrão para o componente Script, use a opção Linguagem de scripts na página Geral da caixa de diálogo Opções. Para obter mais informações, consulte Página Geral.

Um componente de transformação de fluxo de dados tem uma entrada e dá suporte a uma ou mais saídas. A configuração de entrada e saídas do seu componente é uma das etapas que você deve concluir no modo do design de metadados, através do Editor de Transformação Scripts, antes de escrever seu script personalizado.

Configurando colunas de entrada

Um componente de transformação criado através do componente Script tem uma única entrada.

Na página Colunas de Entrada do Editor de Transformação Scripts, a lista de colunas mostra as colunas disponíveis da saída do componente upstream no fluxo de dados. Selecione as colunas que você deseja transformar ou percorrer. Marque qualquer coluna que você queira transformar no local como De leitura/gravação.

Para obter mais informações sobre a página Colunas de Entrada do Editor de Transformação Scripts, consulte Editor de Transformação Scripts (página Colunas de Entrada).

Configurando entradas, saídas e colunas de saída

Um componente de transformação dá suporte a uma ou mais saídas.

Freqüentemente, uma transformação com saídas assíncronas possui duas saídas. Por exemplo, ao contar o número de endereços localizados em uma cidade específica, talvez você queira transmitir os dados do endereço para uma saída, enquanto envia o resultado da agregação para outra saída. A saída de agregação também requer uma coluna de saída nova.

Na página Entradas e Saídas de Editor de Transformação Scripts, note que uma única saída foi criada por padrão, mas nenhuma coluna de saída foi criada. Nessa página do editor, você pode configurar os seguintes itens:

  • Talvez você queira criar uma ou mais saídas adicionais, como uma saída para o resultado de uma agregação. Use os botões Adicionar Saída e Remover Saída para gerenciar as saídas de seu componente de transformação assíncrono. Defina a propriedade SynchronousInputID de cada saída como zero para indicar que a saída não está simplesmente passando dados de um componente upstream, nem transformando-os no local nas linhas e colunas existentes. É essa configuração que torna as saídas assíncronas para a entrada.

  • Talvez você queira atribuir um nome amigável à entrada e saídas. O componente Script utiliza esses nomes para gerar as propriedades de acessador digitadas que você utilizará para referenciar a entrada e as saídas no seu script.

  • Freqüentemente, uma transformação assíncrona adiciona colunas ao fluxo de dados. Quando a propriedade SynchronousInputID de uma saída for zero, indicando que a saída não está simplesmente passando dados de um componente upstream, nem transformando-os no local nas linhas e colunas existentes, adicione e configure colunas de saída de maneira explícita na saída. Colunas de saída não precisam ter os mesmos nomes que as colunas de entrada para as quais elas são mapeadas.

  • Talvez você queira adicionar mais colunas para incluir informações adicionais. Escreva seu próprio código para preencher as colunas adicionais com dados. Para obter informações sobre como reproduzir o comportamento de uma saída de erro padrão, consulte Simulando uma saída de erro para o componente Script.

Para obter mais informações sobre a página Entradas e Saídas do Editor de Transformação Scripts, consulte Editor de Transformação Scripts (página Entradas e Saídas).

Adicionando variáveis

Caso existam variáveis cujos valores você deseja utilizar em seu script, será possível adicioná-las nos campos de propriedade ReadOnlyVariables e ReadWriteVariables da página Script do Editor de Transformação Scripts.

Ao adicionar diversas variáveis aos campos de propriedade, separe os nomes das variáveis com vírgulas. Outra alternativa para selecionar diversas variáveis é clicar no botão de reticências () que fica ao lado dos campos de propriedade ReadOnlyVariables e ReadWriteVariables e depois selecione as variáveis na caixa de diálogo Selecionar variáveis.

Para obter informações gerais sobre como usar variáveis com o componente Script, consulte Usando variáveis no componente Script.

Para obter mais informações sobre a página Script do Editor de Transformação Scripts, consulte Editor de Transformação Scripts (página Script).

Gerando scripts de um componente de transformação assíncrono em modo do design de código

Depois de configurar todos os metadados do seu componente, você poderá escrever seu script personalizado. No Editor de Transformação Scripts, na página Script, clique em Editar Script para abrir o MicrosoftVisual Studio Tools for Applications (VSTA) IDE, onde você pode adicionar o script personalizado. Para saber a linguagem de scripts a ser usada, primeiro verifique se você selecionou a linguagem de script MicrosoftVisual Basic 2008 ou MicrosoftVisual C# 2008 para a propriedade ScriptLanguage na página Script.

Para obter informações importantes que se aplicam a todos os tipos de componentes criados através do componente Script, consulte Codificando e depurando o componente Script.

Compreendendo o código gerado automaticamente

Quando você abrir o VSTA IDE depois de criar e configurar um componente de transformação, a classe editável ScriptMain aparecerá no editor de códigos com stubs para os métodos ProcessInputRow e CreateNewOutputRows. A classe ScriptMain é onde você escreverá seu código personalizado, e ProcessInputRow é o método mais importante em um componente de transformação. O método CreateNewOutputRows costuma ser mais usado em um componente de origem, que é como uma transformação assíncrona pois ambos os componentes devem criar suas próprias linhas de saída.

Se você abrir a janela Explorador de Projeto do VSTA, verificará que o componente Script também gerou BufferWrapper somente leitura e itens de projeto ComponentWrapper. A classe ScriptMain foi herdada da classe UserComponent no item de projeto ComponentWrapper.

Em tempo de execução, o mecanismo de fluxo de dados chama o método PrimeOutput na classe UserComponent que anula o método PrimeOutput da classe pai ScriptComponent. O método PrimeOutput, por sua vez, chama o método CreateNewOutputRows.

Depois, o mecanismo de fluxo de dados invoca o método ProcessInput na classe UserComponent, que anula o método ProcessInput da classe pai ScriptComponent. O método ProcessInput, por sua vez, executa um loop nas linhas do buffer de entrada e chama o método ProcessInputRow uma vez para cada linha.

Escrevendo seu código personalizado

Para concluir a criação de um componente de transformação assíncrono personalizado, utilize o método substituído ProcessInputRow para processar os dados em cada linha do buffer de entrada. Como as saídas não são síncronas para a entrada, escreva explicitamente linhas de dados para as saídas.

Em uma transformação assíncrona, você pode utilizar o método AddRow para adicionar linhas à saída, conforme apropriado dentro do método ProcessInputRow ou ProcessInput. Não é necessário utilizar o método CreateNewOutputRows. Se você estiver escrevendo uma única linha de resultados, como, por exemplo, resultados de agregação, para determinada saída, poderá criar a linha de saída anteriormente através do método CreateNewOutputRows, e preencher seus valores posteriormente, depois de processar todas as linhas de entrada. Contudo, não é útil criar múltiplas linhas no método CreateNewOutputRows, pois o componente Script só permite o uso da linha atual em uma entrada ou saída. O método CreateNewOutputRows é mais importante em um componente de origem onde não há linhas de entrada a serem processadas.

Talvez você também queira substituir o próprio método ProcessInput. Isso permite executar processamento preliminar ou final adicional, antes ou depois do loop pelo buffer de entrada, e chamar ProcessInputRow para cada linha. Por exemplo, um dos exemplos de código nesse tópico substitui o ProcessInput para contar o número de endereços em uma cidade específica, pois ProcessInputRow executa um loop em linhas. O exemplo grava o valor do resumo na segunda saída depois do processamento de todas as linhas. O exemplo completa a saída em ProcessInput porque os buffers de saída não estão mais disponíveis quando PostExecute é chamado.

Dependendo dos seus requisitos, talvez você queira gravar o script nos métodos PreExecute e PostExecute disponíveis na classe ScriptMain para executar qualquer processamento preliminar ou final.

ObservaçãoObservação

Se você estivesse desenvolvendo um componente de fluxo de dados personalizado a partir do zero, seria importante substituir o método PrimeOutput para referências de cache aos buffers de saída a fim de poder adicionar linhas de dados aos buffers posteriormente. No componente Script, isto não é necessário porque você tem uma classe gerada automaticamente que representa cada buffer de saída no item de projeto BufferWrapper.

Exemplo

Esse exemplo demonstra o código personalizado que é requerido na classe ScriptMain para criar um componente de transformação assíncrono.

ObservaçãoObservação

Esses exemplos usam a tabela Person.Address no banco de dados de exemplo AdventureWorks e passam a primeira e a quarta colunas, as colunas intAddressID e nvarchar(30)City, através do fluxo de dados. Os mesmos dados são usados nos exemplos de origem, transformação e destino nessa seção. Pré-requisitos e suposições adicionais são documentados para cada exemplo.

Esse exemplo demonstra um componente de transformação assíncrono com duas saídas. Essa transformação passa pelas colunas AddressID e City para uma saída, enquanto conta o número de endereços localizados em uma cidade específica (Redmond, Washington, Estados Unidos) e, depois, libera o valor resultante para uma segunda saída.

Se você quiser executar esse código de exemplo, configure o pacote e o componente desta forma:

  1. Adicione um novo componente Script à superfície de designer Fluxo de Dados e configure-o como uma transformação.

  2. Conecte a saída de uma origem ou de outra transformação para o novo componente de transformação no designer. Essa saída deve fornecer dados da tabela Person.Address do banco de dados de exemplo AdventureWorks que contém pelo menos as colunas AddressID e City.

  3. Abra o Editor de Transformação Scripts. Na página Colunas de Entrada, selecione as colunas AddressID e City.

  4. Na página Entradas e Saídas, adicione e configure as colunas de saída AddressID e City na primeira saída. Adicione uma segunda saída e uma coluna de saída para obter o valor resumido na segunda saída. Defina a propriedade SynchronousInputID da primeira saída como 0, pois esse exemplo copia cada linha de entrada explicitamente na primeira saída. A propriedade SynchronousInputID da saída recém-criada já está definida como 0.

  5. Renomeie a entrada, as saídas e a nova coluna de saída para atribuir a elas nomes mais descritivos. O exemplo utiliza MyAddressInput como o nome da entrada, MyAddressOutput e MySummaryOutput para as saídas, e MyRedmondCount para a coluna de saída na segunda saída.

  6. Na página Script, clique em Editar Script e digite o script a seguir. Em seguida, feche o ambiente de desenvolvimento de script e o Editor de Transformação Scripts.

  7. Crie e configure um componente de destino para a primeira saída que espera as colunas AddressID e City, tais como um destino do SQL Server ou o componente de destino de exemplo demonstrado em Criando um destino com o componente Script. Depois, conecte a primeira saída da transformação, MyAddressOutput, ao componente de destino. Você pode criar uma tabela de destino executando o seguinte comando Transact-SQL no banco de dados AdventureWorks:

    CREATE TABLE [Person].[Address2](
        [AddressID] [int] NOT NULL,
        [City] [nvarchar](30) NOT NULL
    )
    
  8. Crie e configure outro componente de destino para a segunda saída. Depois, conecte a segunda saída da transformação, MySummaryOutput, ao componente de destino. Como a segunda saída grava uma única linha com um único valor, você pode facilmente configurar um destino com um gerenciador de conexões de arquivo simples que se conecta a um novo arquivo que possui uma única coluna. No exemplo, essa coluna de destino é nomeada MyRedmondCount.

  9. Execute o exemplo.

Public Class ScriptMain
    Inherits UserComponent

    Private myRedmondAddressCount As Integer

    Public Overrides Sub CreateNewOutputRows()

        MySummaryOutputBuffer.AddRow()

    End Sub

    Public Overrides Sub MyAddressInput_ProcessInput(ByVal Buffer As MyAddressInputBuffer)

        While Buffer.NextRow()
            MyAddressInput_ProcessInputRow(Buffer)
        End While

        If Buffer.EndOfRowset Then
            MyAddressOutputBuffer.SetEndOfRowset()
            MySummaryOutputBuffer.MyRedmondCount = myRedmondAddressCount
            MySummaryOutputBuffer.SetEndOfRowset()
        End If

    End Sub

    Public Overrides Sub MyAddressInput_ProcessInputRow(ByVal Row As MyAddressInputBuffer)

        With MyAddressOutputBuffer
            .AddRow()
            .AddressID = Row.AddressID
            .City = Row.City
        End With

        If Row.City.ToUpper = "REDMOND" Then
            myRedmondAddressCount += 1
        End If

    End Sub

End Class
public class ScriptMain:
    UserComponent

{
    private int myRedmondAddressCount;

    public override void CreateNewOutputRows()
    {

        MySummaryOutputBuffer.AddRow();

    }

    public override void MyAddressInput_ProcessInput(MyAddressInputBuffer Buffer)
    {

        while (Buffer.NextRow())
        {
            MyAddressInput_ProcessInputRow(Buffer);
        }

        if (Buffer.EndOfRowset())
        {
            MyAddressOutputBuffer.SetEndOfRowset();
            MySummaryOutputBuffer.MyRedmondCount = myRedmondAddressCount;
            MySummaryOutputBuffer.SetEndOfRowset();
        }

    }

    public override void MyAddressInput_ProcessInputRow(MyAddressInputBuffer Row)
    {

        {
            MyAddressOutputBuffer.AddRow();
            MyAddressOutputBuffer.AddressID = Row.AddressID;
            MyAddressOutputBuffer.City = Row.City;
        }

        if (Row.City.ToUpper() == "REDMOND")
        {
            myRedmondAddressCount += 1;
        }

    }

}
Í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.