Codificando uma tarefa personalizada

Aplica-se a: simSQL Server (todas as versões compatíveis) sim SSIS Integration Runtime no Azure Data Factory

Depois de criar uma classe que herda da classe base Microsoft.SqlServer.Dts.Runtime.Task e aplicar o atributo DtsTaskAttribute a essa classe, você deve substituir a implementação das propriedades e dos métodos da classe base para fornecer a funcionalidade personalizada.

Configurando a tarefa

Validando a tarefa

Ao projetar um pacote do Integration Services, você pode usar a validação para verificar as definições de cada tarefa, de forma a detectar definições incorretas ou inadequadas tão logo sejam definidas, em vez de encontrar todos os erros somente em tempo de execução. O propósito da validação é determinar se a tarefa contém configurações ou conexões inválidas que a impedirão de ser executada com sucesso. Isso garante que o pacote contenha tarefas com boa chance de serem executadas na primeira execução.

Você pode implementar a validação usando o método Validate em código personalizado. O mecanismo de tempo de execução valida uma tarefa chamando o método Validate na tarefa. É responsabilidade do desenvolvedor da tarefa definir os critérios que lhe proporcionem uma validação bem sucedida ou malsucedida da tarefa, e notificar o mecanismo de tempo de execução do resultado dessa avaliação.

Classe base abstrata da tarefa

A classe base abstrata Microsoft.SqlServer.Dts.Runtime.Task fornece o método Validate que cada tarefa substitui para definir os critérios de validação. O SSIS Designer chama automaticamente o método Validate várias vezes durante o projeto do pacote e fornece indicações visuais ao usuário quando ocorrem avisos ou erros para ajudar a identificar problemas com a configuração da tarefa. As tarefas fornecem resultados de validação retornando um valor da enumeração DTSExecResult e gerando eventos de aviso e erro. Esses eventos contêm informações que são exibidas ao usuário no SSIS Designer.

Seguem alguns exemplos de validação:

  • Um gerenciador de conexões valida o nome do arquivo específico.

  • Um gerenciador de conexões valida que o tipo de entrada é o tipo esperado, como um arquivo XML.

  • Uma tarefa que aguarda a entrada de banco de dados verifica se não pode receber dados de uma conexão que não seja de banco de dados.

  • Uma tarefa garante que nenhuma de suas propriedades contradiga outras propriedades definidas na mesma tarefa.

  • Uma tarefa garante que todos os recursos necessários usados pela tarefa em tempo de execução estejam disponíveis.

Desempenho é algo a ser considerado ao determinar o que é validado e o que não é. Por exemplo, a entrada para uma tarefa pode ser uma conexão em uma rede que tem baixa largura de banda ou alto tráfego. A validação poderá levar vários segundos para ser processada se você decidir validar se o recurso está disponível. Outra validação pode causar uma viagem de ida e volta para um servidor que está em demanda alta e a rotina de validação pode ficar lenta. Embora existam muitas propriedades e configurações que podem ser validadas, nem tudo deve ser validado.

  • O código no método Validate também é chamado pelo TaskHost antes de a tarefa ser executada e o TaskHost cancela a execução se a validação falha.

Considerações da interface do usuário durante a validação

A Microsoft.SqlServer.Dts.Runtime.Task inclui uma interface IDTSComponentEvents como um parâmetro para o método Validate. A interface IDTSComponentEvents contém os métodos que são chamados pela tarefa para gerar eventos para o mecanismo de tempo de execução. Os métodos FireWarning e FireError são chamados quando uma condição de aviso ou erro ocorre durante a validação. Ambos os métodos de aviso requerem os mesmos parâmetros, que incluem um código de erro, um componente de origem, descrição, arquivo de Ajuda e informações de contexto da Ajuda. O SSIS Designer usa essas informações para exibir indicações visuais na superfície de design. As indicações visuais fornecidas pelo designer incluem um ícone de exclamação que aparece próximo à tarefa na superfície do designer. Essa indicação visual sinaliza ao usuário que a tarefa requer configuração adicional antes de continuar a execução.

O ícone de exclamação também exibe uma dica de ferramenta que contém uma mensagem de erro. A mensagem de erro é fornecida pela tarefa no parâmetro de descrição do evento. Mensagens de erro também são exibidas no painel Lista de Tarefas do SQL Server Data Tools (SSDT), fornecendo ao usuário um local central para exibir todos os erros de validação.

Exemplo de validação

O exemplo de código seguinte mostra uma tarefa com uma propriedade UserName. Essa propriedade foi especificada conforme solicitado para a validação ter sucesso. Se a propriedade não for definida, a tarefa postará um erro e retornará Failure da enumeração DTSExecResult. O método Validate é quebrado em um bloco de prova/captura e abandona a validação se ocorre uma exceção.

using System;  
using Microsoft.SqlServer.Dts.Runtime;  
  
public class SampleTask : Task  
{  
  private string userName = "";  
  
  public override DTSExecResult Validate(Connections connections,  
     VariableDispenser variableDispenser, IDTSComponentEvents events,  
     IDTSLogging log)  
  {  
    try  
    {  
      if (this.userName == "")  
      {  
        //   Raise an OnError event.  
        events.FireError(0, "SampleTask", "The UserName property must be configured.", "", 0);  
        //   Fail validation.  
        return DTSExecResult.Failure;  
      }  
      //   Return success.  
      return DTSExecResult.Success;  
    }  
    catch (System.Exception exception)  
    {  
      //   Capture exceptions, post an error, and fail validation.  
      events.FireError(0, "Sampletask", exception.Message, "", 0);  
      return DTSExecResult.Failure;  
    }  
  }  
  public string UserName  
  {  
    get  
    {  
      return this.userName;  
    }  
    set  
    {  
      this.userName = value;  
    }  
  }  
}  
Imports System  
Imports Microsoft.SqlServer.Dts.Runtime  
  
Public Class SampleTask  
  Inherits Task  
  
  Private _userName As String = ""  
  
  Public Overrides Function Validate(ByVal connections As Connections, _  
     ByVal variableDispenser As VariableDispenser, _  
     ByVal events As IDTSComponentEvents, _  
     ByVal log As IDTSLogging) As DTSExecResult  
  
    Try  
      If Me._userName = "" Then  
        '   Raise an OnError event.  
        events.FireError(0, "SampleTask", "The UserName property must be configured.", "", 0)  
        '   Fail validation.  
        Return DTSExecResult.Failure  
      End If  
      '   Return success.  
      Return DTSExecResult.Success  
    Catch exception As System.Exception  
      '   Capture exceptions, post an error, and fail validation.  
      events.FireError(0, "Sampletask", exception.Message, "", 0)  
      Return DTSExecResult.Failure  
    End Try  
  
  End Function  
  
  Public Property UserName() As String  
    Get  
      Return Me._userName  
    End Get  
    Set(ByVal Value As String)  
      Me._userName = Value  
    End Set  
  End Property  
  
End Class  

Persistindo a tarefa

Normalmente, não é preciso implementar uma persistência personalizada para uma tarefa. A persistência personalizada é necessária somente quando as propriedades de um objeto usam tipos de dados complexos. Para obter mais informações, consulte Desenvolvendo objetos personalizados para o Integration Services.

Executando a tarefa

Esta seção descreve como usar o método Execute, que é herdado e substituído por tarefas. Esta seção também explica vários modos de fornecer informações sobre os resultados da execução de uma tarefa.

Método Execute

As tarefas contidas em um pacote são executadas quando o runtime do Integration Services chama seu método Execute. As tarefas implementam sua principal lógica de negócios e sua funcionalidade nesse método e fornecem os resultados da execução postando mensagens, retornando um valor da enumeração DTSExecResult e substituindo a propriedade get da propriedade ExecutionValue.

A classe base Microsoft.SqlServer.Dts.Runtime.Task fornece uma implementação padrão do método Execute. As tarefas personalizadas anulam esse método para definir sua funcionalidade de tempo de execução. O objeto TaskHost quebra a tarefa, isolando-a do mecanismo de tempo de execução e dos outros objetos no pacote. Por causa desse isolamento, a tarefa não reconhece sua localização no pacote quanto à ordem de execução e é executada somente quando chamada pelo runtime. Essa arquitetura evita os problemas que podem ocorrer quando as tarefas modificam o pacote durante a execução. A tarefa recebe acesso aos outros objetos do pacote somente por meio dos objetos fornecidos a ela como parâmetros no método Execute. Esses parâmetros permitem que as tarefas gerem eventos, gravem entradas no log de eventos, acessem a coleção de variáveis e inscrevam conexões em fontes de dados nas transações, ao mesmo tempo mantendo o isolamento necessário para garantir a estabilidade e a confiabilidade do pacote.

A tabela seguinte lista os parâmetros fornecidos à tarefa no método Execute.

Parâmetro Descrição
Connections Contém uma coleção de objetos ConnectionManager disponíveis para a tarefa.
VariableDispenser Contém as variáveis disponíveis para a tarefa. As tarefas usam variáveis pelo VariableDispenser; as tarefas não usam variáveis diretamente. O VariableDispenser bloqueia e desbloqueia as variáveis e impede deadlocks ou substituições.
IDTSComponentEvents Contém os métodos chamados pela tarefa para gerar eventos ao mecanismo de tempo de execução.
IDTSLogging Contém métodos e propriedades usados pela tarefa para gravar entradas no log de eventos.
Objeto Contém o objeto de transação do qual o contêiner faz parte, se houver. Esse valor é passado como um parâmetro ao método AcquireConnection de um objeto ConnectionManager.

Fornecendo comentários de execução

As tarefas encapsulam seu código em blocos try/catch para evitar que sejam geradas exceções para o mecanismo de tempo de execução. Isso assegura que o pacote conclua a execução e não pare inesperadamente. Porém, o mecanismo de tempo de execução fornece outros mecanismos para tratar condições de erro que podem ocorrer durante a execução de uma tarefa. Eles incluem postar mensagens de erro e de aviso, retornar um valor da estrutura do DTSExecResult, postar mensagens, retornar o valor DTSExecResult e divulgar informações sobre os resultados da execução da tarefa através da propriedade ExecutionValue.

A interface do IDTSComponentEvents contém os métodos FireWarning e FireError, que podem ser chamados pela tarefa para postar mensagens de erro e de aviso para o mecanismo de tempo de execução. Ambos os métodos requerem parâmetros como código de erro, componente de origem, descrição, arquivo de Ajuda e informações de contexto de ajuda. Dependendo da configuração da tarefa, o runtime responde a essas mensagens gerando eventos e pontos de interrupção, ou gravando informações no log de eventos.

O TaskHost também fornece a propriedade ExecutionValue que pode ser usada para fornecer informações adicionais sobre os resultados da execução. Por exemplo, se uma tarefa exclui linhas de uma tabela como parte do seu método Execute, ela pode retornar o número de linhas excluídas como o valor da propriedade ExecutionValue. Além disso, o TaskHost fornece a propriedade ExecValueVariable. Essa propriedade permite que o usuário mapeie o ExecutionValue retornado da tarefa para qualquer variável visível à tarefa. A variável especificada pode ser usada para estabelecer restrições de precedência entre as tarefas.

Exemplo de execução

O exemplo de código seguinte demonstra uma implementação do método Execute e mostra uma propriedade ExecutionValue substituída. A tarefa exclui o arquivo que é especificado pela propriedade fileName da tarefa. A tarefa posta um aviso se o arquivo não existir ou se a propriedade fileName for uma cadeia de caracteres vazia. A tarefa retorna um valor booliano na propriedade ExecutionValue para indicar se o arquivo foi excluído.

using System;  
using Microsoft.SqlServer.Dts.Runtime;  
  
public class SampleTask : Task  
{  
  private string fileName = "";  
  private bool fileDeleted = false;  
  
  public override DTSExecResult Execute(Connections cons,  
     VariableDispenser vars, IDTSComponentEvents events,  
     IDTSLogging log, Object txn)  
  {  
    try  
    {  
      if (this.fileName == "")  
      {  
        events.FireWarning(0, "SampleTask", "No file specified.", "", 0);  
        this.fileDeleted = false;  
      }  
      else  
      {  
        if (System.IO.File.Exists(this.fileName))  
        {  
          System.IO.File.Delete(this.fileName);  
          this.fileDeleted = true;  
        }  
        else  
          this.fileDeleted = false;  
      }  
      return DTSExecResult.Success;  
    }  
    catch (System.Exception exception)  
    {  
      //   Capture the exception and post an error.  
      events.FireError(0, "Sampletask", exception.Message, "", 0);  
      return DTSExecResult.Failure;  
    }  
  }  
  public string FileName  
  {  
    get { return this.fileName; }  
    set { this.fileName = value; }  
  }  
  public override object ExecutionValue  
  {  
    get { return this.fileDeleted; }  
  }  
}  
Imports System  
Imports Microsoft.SqlServer.Dts.Runtime  
  
Public Class SampleTask  
  Inherits Task  
  
  Private _fileName As String = ""  
  Private _fileDeleted As Boolean = False  
  
  Public Overrides Function Execute(ByVal cons As Connections, _  
     ByVal vars As VariableDispenser, ByVal events As IDTSComponentEvents, _  
     ByVal log As IDTSLogging, ByVal txn As Object) As DTSExecResult  
  
    Try  
      If Me._fileName = "" Then  
        events.FireWarning(0, "SampleTask", "No file specified.", "", 0)  
        Me._fileDeleted = False  
      Else  
        If System.IO.File.Exists(Me._fileName) Then  
          System.IO.File.Delete(Me._fileName)  
          Me._fileDeleted = True  
        Else  
          Me._fileDeleted = False  
        End If  
      End If  
      Return DTSExecResult.Success  
    Catch exception As System.Exception  
      '   Capture the exception and post an error.  
      events.FireError(0, "Sampletask", exception.Message, "", 0)  
      Return DTSExecResult.Failure  
    End Try  
  
  End Function  
  
  Public Property FileName() As String  
    Get  
      Return Me._fileName  
    End Get  
    Set(ByVal Value As String)  
      Me._fileName = Value  
    End Set  
  End Property  
  
  Public Overrides ReadOnly Property ExecutionValue() As Object  
    Get  
      Return Me._fileDeleted  
    End Get  
  End Property  
  
End Class  

Consulte Também

Criar uma tarefa personalizada
Codificar uma tarefa personalizada
Desenvolver uma interface do usuário para uma tarefa personalizada