Cargar la salida de un paquete local
Las aplicaciones cliente pueden leer la salida de los paquetes de Integration Services cuando se guarda la salida en destinos de SQL Server mediante ADO.NET o cuando se guarda en un destino de archivo plano usando las clases del espacio de nombres System.IO. Sin embargo, una aplicación cliente también puede leer la salida de un paquete directamente de la memoria, sin tener que efectuar un paso intermedio para conservar los datos. La clave de esta solución es el Microsoft.SqlServer.Dts.DtsClient
espacio de nombres , que contiene implementaciones especializadas de las IDbConnection
interfaces , IDbCommand
e IDbDataParameter del espacio de nombres System.Data . El ensamblado Microsoft.SqlServer.Dts.DtsClient.dll se instala de forma predeterminada en la carpeta %Archivos de programa%\Microsoft SQL Server\100\DTS\Binn.
Nota:
El procedimiento descrito en este tema necesita que la propiedad DelayValidation de la tarea Flujo de datos y de los objetos primarios esté establecida en el valor predeterminado de False.
Descripción
Este procedimiento muestra cómo desarrollar una aplicación cliente en código administrado que carga la salida de un paquete con un destino DataReader directamente de la memoria. Los pasos resumidos aquí se muestran en el ejemplo de código que figura a continuación.
Para cargar la salida del paquete de datos en una aplicación cliente
En el paquete, configure un destino DataReader para recibir la salida que desea leer en la aplicación cliente. Dé un nombre descriptivo al destino DataReader, dado que utilizará este nombre más adelante en la aplicación cliente. Tome nota del nombre del destino DataReader.
En el proyecto de desarrollo, establezca una referencia al
Microsoft.SqlServer.Dts.DtsClient
espacio de nombres mediante la ubicación del ensamblado Microsoft.SqlServer.Dts.DtsClient.dll. De forma predeterminada, este ensamblado se instala en C:\Archivos de programa\Microsoft SQL Server\100\DTS\Binn. Importe el espacio de nombres en el código mediante la instrucción C#Using
o Visual BasicImports
.En el código, cree un objeto de tipo
DtsClient.DtsConnection
con un cadena de conexión que contenga los parámetros de la línea de comandos requeridos por dtexec.exe para ejecutar el paquete. Para obtener más información, consulte utilidad dtexec. A continuación, abra la conexión con esta cadena de conexión. También puede emplear la utilidad dtexecui para crear visualmente la cadena de conexión necesaria.Nota
En el código de ejemplo se muestra cómo cargar el paquete del sistema de archivos mediante la sintaxis
/FILE <path and filename>
. No obstante, puede también cargar el paquete desde la base de datos MSDB utilizando la sintaxis/SQL <package name>
o desde el almacén de paquetes de Integration Services utilizando la sintaxis/DTS \<folder name>\<package name>
.Cree un objeto de tipo
DtsClient.DtsCommand
que utiliza el objetoDtsConnection
creado anteriormente y establezca la propiedadCommandText
en el nombre del destino DataReader del paquete. A continuación, llame al métodoExecuteReader
del objeto de comando para cargar los resultados del paquete en un nuevo DataReader.Opcionalmente, puede parametrizar indirectamente la salida del paquete utilizando la colección de objetos
DtsDataParameter
en el objetoDtsCommand
para pasar los valores a las variables definidas en el paquete. Dentro del paquete, puede usar estas variables como parámetros de consulta o en expresiones para influir en los resultados devueltos al destino DataReader. Debe definir estas variables en el paquete en el espacio de nombres DtsClient para poder usarlas con elDtsDataParameter
objeto de una aplicación cliente. (Es posible que tenga que hacer clic en el Elija el botón de la barra de herramientas Columnas variables de la ventana Variables para mostrar la columna Espacio de nombres ). En el código de cliente, al agregar unDtsDataParameter
elemento a laParameters
colección de ,DtsCommand
omita la referencia de espacio de nombres DtsClient del nombre de la variable. Por ejemplo:command.Parameters.Add(new DtsDataParameter("MyVariable", 1));
Llame al método
Read
de DataReader repetidamente según sea necesario para recorrer en bucle las filas de datos de salida. Utilice los datos, o guárdelos para un uso posterior, en la aplicación cliente.Importante
El método
Read
de esta implementación de DataReader devuelvetrue
una o varias veces después de leer la última fila de datos. Esto hace que sea difícil utilizar el código usual que recorre en bucle DataReader mientrasRead
devuelvetrue
. Si el código intenta cerrar DataReader o la conexión después de leer el número esperado de filas, sin una llamada adicional, final al métodoRead
, el código producirá una excepción no controlada. Sin embargo, si el código intenta leer datos en esta iteración final a través de un bucle, cuandoRead
todavía devuelvetrue
pero se ha pasado la última fila, el código generará un error no controladoApplicationException
con el mensaje "SSIS IDataReader está más allá del final del conjunto de resultados". Este comportamiento es diferente del de otras implementaciones de DataReader. Por consiguiente, si utiliza un bucle para leer las filas de DataReader mientrasRead
devuelvetrue
, tiene que escribir el código para capturar, probar y descartar estaApplicationException
anticipada en la última llamada correcta al métodoRead
. O bien, si conoce de antemano el número de filas esperado, puede procesar las filas y, a continuación, llamar al métodoRead
un vez más antes de cerrar DataReader y la conexión.Llame al método
Dispose
del objetoDtsCommand
. Esto es particularmente importante si ha utilizado cualquier objetoDtsDataParameter
.Cierre DataReader y los objetos de conexión.
Ejemplo
En el ejemplo siguiente se ejecuta un paquete que calcula un valor de agregado único y guarda el valor en un destino DataReader y, a continuación, lee este valor de DataReader y muestra el valor en un cuadro de texto en un formulario Windows Forms.
No se requiere el uso de parámetros al cargar la salida de un paquete en una aplicación cliente. Si no desea usar un parámetro, puede omitir el uso de la variable en el espacio de nombres DtsClient y omitir el código que usa el DtsDataParameter
objeto .
Para crear el paquete de prueba
Cree un nuevo paquete de Integration Services. En el código de ejemplo se utiliza "DtsClientWParamPkg.dtsx" como el nombre del paquete.
Agregue una variable de tipo String en el espacio de nombres DtsClient. En el ejemplo de código se usa Country como el nombre de la variable. (Quizá tenga que hacer clic en el botón de la barra de herramientas Elegir columnas de variables de la ventana Variables para mostrar la columna Espacio de nombres).
Agregue un administrador de conexiones OLE DB que se conecte a la base de datos de ejemplo AdventureWorks2012.
Agregue una tarea Flujo de datos al paquete y cambie a la superficie de diseño Flujo de datos.
Agregue un origen OLE DB al flujo de datos y configúrelo para utilizar el administrador de conexiones OLE DB creado anteriormente y el comando SQL siguiente:
SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?
Haga clic
Parameters
en y, en el cuadro de diálogo Establecer parámetros de consulta, asigne el único parámetro de entrada de la consulta, Parameter0, a la variable DtsClient::Country.Agregue una transformación Agregado al flujo de datos y conecte la salida del origen OLE DB a la transformación. Abra el Editor de transformación Agregado y configúrelo para realizar una operación "Contar todo" en todas las columnas de entrada (*) y para generar el valor agregado con el alias CustomerCount.
Agregue un destino DataReader al flujo de datos y conecte la salida de transformación Agregado al destino DataReader. En el código de ejemplo se utiliza "DataReaderDest" como el nombre del DataReader. Seleccione una columna de entrada disponible única, CustomerCount, para el destino.
Guarde el paquete. La aplicación de prueba creada a continuación ejecutará el paquete y recuperará la salida directamente de la memoria.
Para crear la aplicación de prueba
Cree una nueva aplicación Windows Forms.
Agregue una referencia al
Microsoft.SqlServer.Dts.DtsClient
espacio de nombres; para ello, vaya al ensamblado del mismo nombre en %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn.Copie y pegue el código muestra siguiente en el módulo de código del formulario.
Modifique el valor de la
dtexecArgs
variable según sea necesario para que contenga los parámetros de la línea de comandos requeridos por dtexec.exe para ejecutar el paquete. En el código muestra se carga el paquete desde el sistema de archivos.Modifique el valor de la
dataReaderName
variable según sea necesario para que contenga el nombre del destino DataReader en el paquete.Coloque un botón y un cuadro de texto en el formulario. El código de ejemplo usa
btnRun
como nombre del botón ytxtResults
como nombre del cuadro de texto.Ejecute la aplicación y haga clic en el botón. Después de una breve pausa mientras el paquete se ejecuta, debería aparecer en el cuadro de texto del formulario el valor agregado calculado por el paquete (el recuento de clientes de Canadá).
Código de ejemplo
Imports System.Data
Imports Microsoft.SqlServer.Dts.DtsClient
Public Class Form1
Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
Dim dtexecArgs As String
Dim dataReaderName As String
Dim countryName As String
Dim dtsConnection As DtsConnection
Dim dtsCommand As DtsCommand
Dim dtsDataReader As IDataReader
Dim dtsParameter As DtsDataParameter
Windows.Forms.Cursor.Current = Cursors.WaitCursor
dtexecArgs = "/FILE ""C:\...\DtsClientWParamPkg.dtsx"""
dataReaderName = "DataReaderDest"
countryName = "Canada"
dtsConnection = New DtsConnection()
With dtsConnection
.ConnectionString = dtexecArgs
.Open()
End With
dtsCommand = New DtsCommand(dtsConnection)
dtsCommand.CommandText = dataReaderName
dtsParameter = New DtsDataParameter("Country", DbType.String)
dtsParameter.Direction = ParameterDirection.Input
dtsCommand.Parameters.Add(dtsParameter)
dtsParameter.Value = countryName
dtsDataReader = dtsCommand.ExecuteReader(CommandBehavior.Default)
With dtsDataReader
.Read()
txtResults.Text = .GetInt32(0).ToString("N0")
End With
'After reaching the end of data rows,
' call the Read method one more time.
Try
dtsDataReader.Read()
Catch ex As Exception
MessageBox.Show("Exception on final call to Read method:" & ControlChars.CrLf & _
ex.Message & ControlChars.CrLf & _
ex.InnerException.Message, "Exception on final call to Read method", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
' The following method is a best practice, and is
' required when using DtsDataParameter objects.
dtsCommand.Dispose()
Try
dtsDataReader.Close()
Catch ex As Exception
MessageBox.Show("Exception closing DataReader:" & ControlChars.CrLf & _
ex.Message & ControlChars.CrLf & _
ex.InnerException.Message, "Exception closing DataReader", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Try
dtsConnection.Close()
Catch ex As Exception
MessageBox.Show("Exception closing connection:" & ControlChars.CrLf & _
ex.Message & ControlChars.CrLf & _
ex.InnerException.Message, "Exception closing connection", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Windows.Forms.Cursor.Current = Cursors.Default
End Sub
End Class
using System;
using System.Windows.Forms;
using System.Data;
using Microsoft.SqlServer.Dts.DtsClient;
namespace DtsClientWParamCS
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
}
private void btnRun_Click(object sender, EventArgs e)
{
string dtexecArgs;
string dataReaderName;
string countryName;
DtsConnection dtsConnection;
DtsCommand dtsCommand;
IDataReader dtsDataReader;
DtsDataParameter dtsParameter;
Cursor.Current = Cursors.WaitCursor;
dtexecArgs = @"/FILE ""C:\...\DtsClientWParamPkg.dtsx""";
dataReaderName = "DataReaderDest";
countryName = "Canada";
dtsConnection = new DtsConnection();
{
dtsConnection.ConnectionString = dtexecArgs;
dtsConnection.Open();
}
dtsCommand = new DtsCommand(dtsConnection);
dtsCommand.CommandText = dataReaderName;
dtsParameter = new DtsDataParameter("Country", DbType.String);
dtsParameter.Direction = ParameterDirection.Input;
dtsCommand.Parameters.Add(dtsParameter);
dtsParameter.Value = countryName;
dtsDataReader = dtsCommand.ExecuteReader(CommandBehavior.Default);
{
dtsDataReader.Read();
txtResults.Text = dtsDataReader.GetInt32(0).ToString("N0");
}
//After reaching the end of data rows,
// call the Read method one more time.
try
{
dtsDataReader.Read();
}
catch (Exception ex)
{
MessageBox.Show(
"Exception on final call to Read method:\n" + ex.Message + "\n" + ex.InnerException.Message,
"Exception on final call to Read method", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// The following method is a best practice, and is
// required when using DtsDataParameter objects.
dtsCommand.Dispose();
try
{
dtsDataReader.Close();
}
catch (Exception ex)
{
MessageBox.Show(
"Exception closing DataReader:\n" + ex.Message + "\n" + ex.InnerException.Message,
"Exception closing DataReader", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
dtsConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(
"Exception closing connection:\n" + ex.Message + "\n" + ex.InnerException.Message,
"Exception closing connection", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Cursor.Current = Cursors.Default;
}
}
}
Mantenerse al día con Integration Services
Para obtener las descargas, artículos, ejemplos y vídeos más recientes de Microsoft, así como soluciones seleccionadas de la comunidad, visite la página Integration Services en MSDN:
Visite la página de Integration Services en MSDN
Para recibir notificaciones automáticas de estas actualizaciones, suscríbase a las fuentes RSS disponibles en la página.
Consulte también
Descripción de las diferencias entre la carga local y la ejecuciónremota de un paquete local mediante programacióny la ejecución de un paquete remoto mediante programación