Codificar una tarea personalizada
Una vez creada una clase que hereda de la clase base Task y aplicar el atributo DtsTaskAttribute a la clase, debe invalidar la implementación de las propiedades y métodos de la clase base para proporcionar su funcionalidad personalizada.
Configurar la tarea
Validar la tarea
Al diseñar un paquete de Integration Services, puede usar la validación para comprobar la configuración en cada tarea, de manera que pueda detectar los valores incorrectos o inadecuados en cuanto se establezcan, en lugar de buscar todos los errores sólo en tiempo de ejecución. El propósito de la validación es determinar si la tarea contiene conexiones o valores no válidos que impedirán que se ejecute correctamente. De esta manera se garantiza que el paquete contiene tareas con muchas posibilidades de que se ejecuten en su primera ejecución.
Puede implementar la validación mediante el método Validate en código personalizado. El motor en tiempo de ejecución valida una tarea mediante una llamada al método Validate en la tarea. Es responsabilidad del programador de la tarea definir los criterios que dan como correcta o errónea una validación de tarea, así como notificar el motor en tiempo de ejecución del resultado de esta evaluación.
Clase base abstracta Task
La clase base abstracta Task proporciona el método Validate que invalida cada tarea para definir sus criterios de validación. El Diseñador SSIS llama automáticamente varias veces al método Validate durante el diseño del paquete y, cuando se producen advertencias o errores, proporciona al usuario indicaciones visuales que le sirven de ayuda para identificar cualquier problema con la configuración de la tarea. Las tareas proporcionan los resultados de la validación devolviendo un valor de la enumeración DTSExecResult y provocando eventos de errores y advertencias. Estos eventos contienen información que se muestra al usuario en el Diseñador SSIS.
A continuación, se enumeran algunos ejemplos de validación:
Un administrador de conexiones valida el nombre de archivo específico.
Un administrador de conexiones valida que el tipo de entrada es el tipo esperado, como un archivo XML.
Una tarea que espera la base de datos de entrada comprueba que no puede recibir datos de una conexión que no corresponde a una base de datos.
Una tarea garantiza que ninguno de sus propiedades contradice otras propiedades establecidas en la misma tarea.
Una tarea garantiza que están disponibles todos los recursos necesarios que usa la tarea en tiempo de ejecución.
El rendimiento es algo que hay que tener en cuenta para determinar lo que se valida y lo que no. Por ejemplo, la entrada para una tarea podría ser una conexión a través de una red que tiene poco ancho banda o mucha intensidad de tráfico. La validación puede tardar varios segundos para procesar si decide validar que el recurso está disponible. Otra validación puede producir un viaje de ida y vuelta (round trip) a un servidor de gran demanda y la rutina de validación podría ser lenta. Aunque hay muchas propiedades y configuraciones que se pueden validar, no se debería validar todo.
Consideraciones de interfaz de usuario durante la validación
Task incluye una interfaz IDTSComponentEvents como un parámetro para el método Validate. La interfaz IDTSComponentEvents contiene los métodos a los que llama la tarea para producir eventos en el motor en tiempo de ejecución. Se llama a los métodos FireError y FireWarning cuando se produce una advertencia o condición de error durante la validación. Ambos métodos de advertencia requieren los mismos parámetros que incluyen un código de error, componente de origen, descripción, archivo de Ayuda e información de contexto de ayuda. El Diseñador SSIS usa esta información para mostrar indicaciones visuales en la superficie de diseño. Las indicaciones visuales que proporciona el diseñador incluyen un icono de exclamación que aparece junto a la tarea en la superficie del diseñador. Esta indicación visual muestra al usuario que la tarea requiere configuración adicional antes de que la ejecución pueda continuar.
El icono de exclamación también muestra una información sobre herramientas que contiene un mensaje de error. La tarea proporciona el mensaje de error en el parámetro de descripción del evento. Los mensajes de error también se muestran en el panel Lista de tareas de Business Intelligence Development Studio, proporcionando al usuario una ubicación central para ver todos los errores de validación.
Ejemplo de validación
En el ejemplo de código siguiente se muestra una tarea con una propiedad UserName. Esta propiedad se ha especificado como la propiedad necesaria para que la validación sea correcta. Si no se establece la propiedad, la tarea expone un error y devuelve Failure de la enumeración DTSExecResult. El método Validate se ajusta en un bloque try/catch y produce un error en la validación si se produce una excepción.
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
Conservar la tarea
Normalmente, no tiene que implementar la persistencia personalizada para una tarea. Sólo se requiere la persistencia personalizada cuando las propiedades de un objeto usan tipos de datos complejos. Para obtener más información, vea Desarrollar objetos personalizados para Integration Services.
Ejecutar la tarea
En esta sección se describe cómo usar el método Execute que las tareas heredan e invalidan. En esta sección también se explican varias maneras de proporcionar información sobre los resultados de la ejecución de la tarea.
Método Execute
Las tareas que están incluidas en un paquete se ejecutan cuando el tiempo de ejecución de Integration Services llama a su método Execute. Las tareas implementan su lógica de negocios y funcionalidad principal en este método y proporcionan los resultados de ejecución al exponer mensajes, devolver un valor de la enumeración DTSExecResult e invalidar la propiedad get de la propiedad ExecutionValue.
La clase base Task proporciona una implementación predeterminada del método Execute. Las tareas personalizadas invalidan este método para definir su funcionalidad en tiempo de ejecución. El objeto TaskHost ajusta la tarea, aislándola del motor en tiempo de ejecución y de los demás objetos del paquete. Debido a este aislamiento, la tarea no es consciente de su ubicación en el paquete con respecto a su orden de ejecución, y se ejecuta únicamente cuando se llama por el tiempo de ejecución. Esta arquitectura evita los problemas que se pueden producir cuando las tareas modifican el paquete durante la ejecución. La tarea proporciona acceso a los demás objetos del paquete únicamente a través de los objetos que se le suministran como parámetros en el método Execute. Estos parámetros permiten que las tareas produzcan eventos, escriban las entradas en el registro de eventos, tengan acceso a la colección de variables y den de alta las conexiones a los orígenes de datos en transacciones, a la vez que se mantiene todavía el aislamiento necesario para garantizar la estabilidad y confiabilidad del paquete.
En la tabla siguiente se enumeran los parámetros que se proporcionan a la tarea en el método Execute.
Parámetros |
Descripción |
---|---|
Contiene una colección de objetos ConnectionManager disponibles para la tarea. |
|
Contiene las variables disponibles para la tarea. Las tareas usan variables a través de VariableDispenser; las tareas no usan directamente las variables. VariableDispenser bloquea y desbloquea las variables y evita los interbloqueos o sobrescrituras. |
|
Contiene los métodos que la tarea llama para producir eventos en el motor en tiempo de ejecución. |
|
Contiene los métodos y propiedades que usa la tarea para escribir entradas en el registro de eventos. |
|
Objeto |
Contiene el objeto de transacción del que forma parte el contenedor, si existe. Este valor se pasa como un parámetro al método AcquireConnection de un objeto ConnectionManager. |
Proporcionar comentarios de ejecución
Las tareas ajustan su código en bloques try/catch para evitar que se generen excepciones en el motor en tiempo de ejecución. Esto asegura que el paquete termina la ejecución y no se detiene de forma inesperada. Sin embargo, el motor en tiempo de ejecución proporciona otros mecanismos para controlar las condiciones de error que se pueden producir durante la ejecución de una tarea. Estos mecanismos incluyen la exposición de mensajes de error y advertencia, la devolución de un valor de la estructura DTSExecResult, la exposición de mensajes, la devolución del valor DTSExecResult y la divulgación de información acerca de los resultados de ejecución de la tarea a través de la propiedad ExecutionValue.
La interfaz IDTSComponentEvents contiene los métodos FireError y FireWarning, a los que la tarea puede llamar para exponer mensajes de error y advertencia en el motor en tiempo de ejecución. Ambos métodos requieren parámetros como el código de error, componente de origen, descripción, archivo de Ayuda e información de contexto de ayuda. Dependiendo de la configuración de la tarea, el tiempo de ejecución responde a estos mensajes provocando eventos y puntos de interrupción o escribiendo información en el registro de eventos.
TaskHost también facilita la propiedad ExecutionValue que se usa para proporcionar la información adicional sobre los resultados de ejecución. Por ejemplo, si una tarea elimina las filas de una tabla como parte de su método Execute, podría devolver el número de filas eliminadas como el valor de la propiedad ExecutionValue. Además, TaskHost proporciona la propiedad ExecValueVariable. Esta propiedad permite al usuario asignar la propiedad ExecutionValue que devuelve la tarea a cualquier variable visible en la tarea. En ese momento la variable especificada se puede usar para establecer las restricciones de precedencia entre las tareas.
Ejemplo de ejecución
En el ejemplo de código siguiente se muestra una implementación del método Execute y se expone una propiedad ExecutionValue invalidada. La tarea elimina el archivo que especifica la propiedad fileName de la tarea. La tarea expone una advertencia si el archivo no existe, o si la propiedad fileName es una cadena vacía. La tarea devuelve un valor Boolean en la propiedad ExecutionValue para indicar si se eliminó el archivo.
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
|