Crear una transformación asincrónica con el componente de script
Un componente de transformación se utiliza en el flujo de datos de un paquete de Integration Services para modificar y analizar los datos cuando pasan del origen al destino. Una transformación con salidas sincrónicas procesa cada fila de entrada a medida que pasa por el componente. Una transformación con salidas asincrónicas puede esperar hasta haber recibido todas las filas de entrada para completar su procesamiento o puede generar algunas filas antes de haber recibido todas las filas de entrada. En este tema se describe una transformación asincrónica. Si su procesamiento requiere una transformación sincrónica, vea Crear una transformación sincrónica con el componente de script. Para obtener más información acerca de las diferencias que existen entre los componentes sincrónicos y asincrónicos, vea Descripción de las transformaciones sincrónicas y asincrónicas.
Para obtener información general acerca del componente de script, vea Ampliar el flujo de datos con el componente de script.
El componente de script y el código de infraestructura generado por dicho componente simplifican el proceso de desarrollo de un componente de flujo de datos personalizado. No obstante, para entender cómo funciona el componente de script, puede resultarle útil leer los pasos que hay que seguir para desarrollar un componente de flujo de datos personalizado en la sección Desarrollar un componente de flujo de datos personalizado y, especialmente, en Desarrollar un componente de transformación personalizado con salidas sincrónicas.
Introducción a un componente de transformación asincrónica
Al agregar un componente de script a la ficha Flujo de datos del Diseñador SSIS se muestra el cuadro de diálogo Seleccionar el tipo de componente de script, que solicita al usuario que preconfigure el componente como un origen, una transformación o un destino. En este cuadro de diálogo, seleccione Transformación.
Configurar un componente de transformación asincrónica en el modo de diseño de metadatos
Después de seleccionar la opción para crear un componente de transformación, configure el componente mediante el Editor de transformación Script. Para obtener más información, vea Configurar el componente de script en el editor de componentes de script.
Para seleccionar el lenguaje de script que usará el componente de script, establezca la propiedad ScriptLanguage en la página Script del cuadro de diálogo Editor de transformación Script.
[!NOTA]
Para establecer el lenguaje de script predeterminado para el componente de script, utilice la opción Lenguaje de script en la página General del cuadro de diálogo Opciones. Para obtener más información, vea Página General.
Un componente de transformación de flujo de datos tiene una entrada y admite una o varias salidas. La configuración de la entrada y las salidas del componente es uno de los pasos que debe completar en el modo de diseño de metadatos, mediante el Editor de transformación Script, antes de escribir un script personalizado.
Configurar las columnas de entrada
Un componente de transformación creado mediante el componente de script tiene una única entrada.
En la página Columnas de entrada del Editor de transformación Script, la lista de columnas muestra las columnas disponibles de la salida del componente de nivel superior en el flujo de datos. Seleccione las columnas que desee transformar o las columnas a través de las que desee pasar. Marque todas las columnas que desee transformar en contexto como de columnas de lectura/escritura.
Para obtener más información acerca de la página Columnas de entrada del Editor de transformación Script, vea Editor de transformación Script (página Columnas de entrada).
Configurar entradas, salidas y columnas de salidas
Un componente de transformación admite una o más salidas.
A menudo, una transformación con salidas asincrónicas tiene dos salidas. Por ejemplo, al contar el número de direcciones ubicadas en una ciudad concreta, es posible que desee pasar los datos de dirección a una salida y enviar el resultado de la agregación a otra salida distinta. La salida de la agregación también requiere una nueva columna de salida.
En la página Entradas y salidas del Editor de transformación Script, verá que se ha creado una única salida de forma predeterminada, pero que no se ha creado ninguna columna de salida. En esta página del editor, puede configurar los elementos siguientes:
Es posible que desee crear una o más salidas adicionales, como una salida para el resultado de una agregación. Use los botones Agregar salida y Quitar salida para administrar las salidas del componente de transformación asincrónica. Establezca la propiedad SynchronousInputID de cada salida en cero para indicar que la salida no se limita a pasar datos de un componente de nivel superior ni a transformarlos en contexto en las filas y columnas existentes. Este valor hace que las salidas sean asincrónicas con respecto a la entrada.
Es posible que desee asignar un nombre descriptivo a la entrada y a las salidas. El componente de script utiliza estos nombres para generar las propiedades de descriptor de acceso con tipo que se usarán para hacer referencia a la entrada y a las salidas en el script.
A menudo, una transformación asincrónica agrega columnas al flujo de datos. Cuando la propiedad SynchronousInputID de una salida es cero (lo que indica que la salida no se limita a pasar datos de un componente de nivel superior ni a transformarlos en contexto en las filas y columnas existentes), debe agregar y configurar columnas de salida explícitamente en la salida. Las columnas de salida no tienen por qué tener los mismos nombres que las columnas de entrada a las que están asignadas.
Es posible que desee agregar más columnas para incluir información adicional. Debe escribir su propio código para rellenar de datos las columnas adicionales. Para obtener información acerca de la forma de reproducir el comportamiento de una salida de error estándar, vea Simular una salida de error para el componente de script.
Para obtener más información acerca de la página Entradas y salidas del Editor de transformación Script, vea Editor de transformación Script (página Entradas y salidas).
Agregar variables
Si desea usar en su script valores de variables ya existentes, puede agregar estas variables a los campos de propiedades de ReadOnlyVariables y ReadWriteVariables en la página Script del Editor de transformación Script.
Cuando agregue varias variables a los campos de propiedades, separe sus nombres con comas. Para seleccionar varias variables, también puede hacer clic en el botón de puntos suspensivos (…) situado junto a los campos de propiedades ReadOnlyVariables y ReadWriteVariables y, a continuación, seleccionar las variables en el cuadro de diálogo Seleccionar variables.
Para obtener información general acerca de la forma de usar variables con el componente de script, vea Utilizar variables en el componente de script.
Para obtener más información acerca de la página Script del Editor de transformación Script, vea Editor de transformación Script (página Script).
Crear scripts de un componente de transformación asincrónica en el modo de diseño de código
Después de haber configurado todos los metadatos para el componente, puede escribir un script personalizado. En la página Script del Editor de transformación Script, haga clic en Editar script para abrir el IDE de MicrosoftVisual Studio Tools for Applications (VSTA), donde puede agregar el script personalizado. El lenguaje de script que utilice dependerá de si ha seleccionado MicrosoftVisual Basic 2008 o MicrosoftVisual C# 2008 como lenguaje de script para la propiedad ScriptLanguage en la página Script.
Para obtener información importante aplicable a todos los tipos de componentes creados mediante el componente de script, vea Codificar y depurar el componente de script.
Descripción del código generado automáticamente
Al abrir el IDE de VSTA después de crear y configurar un componente de transformación, aparece en el editor de código la clase modificable ScriptMain con códigos auxiliares para los métodos ProcessInputRow y CreateNewOutputRows. En la clase ScriptMain se escribirá el código personalizado, y ProcessInputRow es el método más importante de un componente de transformación. El método CreateNewOutputRows se utiliza con más frecuencia en un componente de origen, que es la forma en que una transformación asincrónica en los dos componentes mencionados debe crear sus propias filas de salida.
Si abre la ventana Explorador de proyectos de VSTA, puede ver que el componente de script también ha generado elementos de proyecto BufferWrapper y ComponentWrapper de sólo lectura. La clase ScriptMain hereda de la clase UserComponent en el elemento de proyecto ComponentWrapper.
En tiempo de ejecución, el motor de flujo de datos llama al método PrimeOutput de la clase UserComponent, lo que invalida el método PrimeOutput de la clase primaria ScriptComponent. El método PrimeOutput llama a su vez al método CreateNewOutputRows.
A continuación, el motor de flujo de datos invoca al método ProcessInput de la clase UserComponent, lo que invalida el método ProcessInput de la clase primaria ScriptComponent. A su vez, el método ProcessInput recorre las filas del búfer de entrada y llama al método ProcessInputRow una vez por cada fila.
Escribir código personalizado
Para terminar de crear un componente de transformación asincrónica personalizado, debe usar el método ProcessInputRow invalidado para procesar los datos de cada fila del búfer de entrada. Dado que las salidas no son sincrónicas con respecto a la entrada, debe escribir filas de datos explícitamente para las salidas.
En una transformación asincrónica, puede usar el método AddRow para agregar filas a la salida, según corresponda, desde los métodos ProcessInputRow o ProcessInput. No es necesario usar el método CreateNewOutputRows. Si escribe una sola fila de resultados (como resultados de agregación) para una salida determinada, puede crear la fila de salida de antemano con el método CreateNewOutputRows y rellenar sus valores más adelante, después de procesar todas las filas de entrada. Sin embargo, no resulta útil crear varias filas en el método CreateNewOutputRows, ya que el componente de script solamente permite usar la fila actual en una entrada o salida. El método CreateNewOutputRows es más importante en un componente de origen donde no hay filas de entrada que procesar.
Puede que también desee invalidar el propio método ProcessInput para poder realizar un procesamiento adicional preliminar o final antes o después de recorrer el búfer de entrada y llamar a ProcessInputRow para cada fila. Así, uno de los ejemplos de código de este tema invalida ProcessInput para contar el número de direcciones de una ciudad concreta como bucles ProcessInputRow a través de las filas. En el ejemplo, el valor de resumen se escribe en la segunda salida una vez procesadas todas las filas. El ejemplo completa la salida de ProcessInput porque los búferes de salida ya no están disponibles al llamar a PostExecute.
En función de sus requisitos, puede que también desee escribir scripts en los métodos PreExecute y PostExecute, disponibles en la clase ScriptMain, para realizar un procesamiento preliminar o final.
[!NOTA]
Si estuviese desarrollando un componente de flujo de datos personalizado partiendo de cero, sería importante que invalidase el método PrimeOutput para almacenar en caché las referencias a los búferes de salida de forma que pudiese agregar filas de datos a los búferes más adelante. Esto no es necesario en el componente de script, ya que existe una clase que se genera automáticamente que representa cada búfer de salida en el elemento de proyecto BufferWrapper.
Ejemplo
En este ejemplo se muestra el código personalizado que se requiere en la clase ScriptMain para crear un componente de transformación asincrónica.
[!NOTA]
Estos ejemplos usan la tabla Person.Address de la base de datos de ejemplo AdventureWorks y pasan la primera y la cuarta columna, las columnas intAddressID y nvarchar(30)City, a través del flujo de datos. Estos mismos datos se usan en los ejemplos de origen, transformación y destino de esta sección. Se documentan requisitos previos y suposiciones adicionales para cada ejemplo.
En este ejemplo se muestra un componente de transformación asincrónica con dos salidas. Esta transformación pasa las columnas AddressID y City a una salida, al mismo tiempo que cuenta el número de direcciones situadas en una ciudad concreta (Redmond, Washington, EE.UU.) y, a continuación, genera el valor resultante en una segunda salida.
Si desea ejecutar este código de ejemplo, debe configurar el paquete y el componente de la siguiente forma:
Agregue un nuevo componente de script a la superficie del diseñador de flujo de datos y configúrelo como una transformación.
Conecte la salida de un origen o de otra transformación al nuevo componente de transformación en el diseñador. Esta salida debe proporcionar datos de la tabla Person.Address de la base de datos de ejemplo AdventureWorks, que contiene al menos las columnas AddressID y City.
Abra el Editor de transformación Script. En la página Columnas de entrada, seleccione las columnas AddressID y City.
En la página Entradas y salidas, agregue y configure las columnas de salida AddressID y City en la primera salida. Agregue una segunda salida y una columna de salida para el valor de resumen en la segunda salida. Establezca la propiedad SynchronousInputID de la primera salida en 0, porque este ejemplo copia cada fila de entrada explícitamente en la primera salida. La propiedad SynchronousInputID de la salida recién creada ya está establecida en 0.
Cambie el nombre de la entrada, las salidas y la nueva columna de salida por nombres más descriptivos. En el ejemplo se usa MyAddressInput como nombre de la entrada, MyAddressOutput y MySummaryOutput para las salidas y MyRedmondCount para la columna de salida de la segunda salida.
En la página Script, haga clic en Editar script y escriba el script que se indica a continuación. A continuación, cierre el entorno de desarrollo de scripts y el Editor de transformación Script.
Cree y configure un componente de destino para la primera salida que espere las columnas AddressID y City, como un destino de SQL Server, o el componente de destino de ejemplo que se muestra en Crear un destino con el componente de script. A continuación, conecte la primera salida de la transformación, MyAddressOutput, al componente de destino. Puede crear una tabla de destino ejecutando el siguiente comando Transact-SQL en la base de datos AdventureWorks:
CREATE TABLE [Person].[Address2]( [AddressID] [int] NOT NULL, [City] [nvarchar](30) NOT NULL )
Cree y configure otro componente de destino para la segunda salida. A continuación, conecte la segunda salida de la transformación, MySummaryOutput, al componente de destino. Dado que la segunda salida escribe una única fila con un único valor, puede configurar fácilmente un destino con un administrador de conexiones de archivos planos que se conecta a un nuevo archivo que tiene una única columna. En el ejemplo, esta columna de destino se denomina MyRedmondCount.
Ejecute el ejemplo.
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;
}
}
}
|