Ejecutar un paquete de SSIS mediante programación en un equipo remoto
Si un equipo cliente (local) no tiene Integration Services instalado o no tiene acceso a todos los recursos necesarios para un paquete, se debe iniciar el paquete de forma que se ejecute en el equipo remoto en el que está almacenado. Debe tomar pasos adicionales para asegurarse de que el paquete se ejecuta en el equipo remoto, porque un paquete se ejecuta en el mismo equipo que la aplicación que lo inicia. Por ello, si ejecuta un paquete remoto directamente desde una aplicación del equipo local, dicho paquete se cargará y ejecutará desde el equipo local. En el caso de que el equipo local no tenga Integration Services instalado, o no tenga acceso a todos los recursos necesarios para el paquete, el paquete no se ejecutará correctamente.
Nota
Un equipo cliente podría no tener Integration Services instalado porque las condiciones de la licencia de SQL Server no permiten instalar Integration Services en equipos adicionales. (Integration Services es un componente de servidor y no se puede distribuir entre equipos cliente.) Sin embargo, si el equipo local tiene Integration Services instalado y tiene acceso a todos los recursos necesarios para el paquete, puede utilizar el equipo local para ejecutar un paquete remoto. Para obtener más información, vea Ejecutar un paquete de SSIS mediante programación en el equipo local.
Para iniciar el paquete en el equipo remoto, debe llamar a uno de los siguientes programas:
Agente de SQL Server.
Otra aplicación, componente o servicio web que se esté ejecutando en el equipo remoto.
Secciones de este tema
|
Requisitos previos del equipo remoto
Tiene que asegurarse de que el proceso que ejecuta el paquete en el equipo remoto tiene los permisos necesarios. Este proceso exige permisos para iniciar el paquete y, además, para buscar y abrir todos los recursos que utiliza el paquete. Los permisos predeterminados son a menudo insuficientes, sobre todo en una solución basada en web. Una descripción completa de los permisos, y de la autenticación y autorización, está más allá del ámbito de este tema.
La suplantación de otra cuenta para ejecutar el paquete no suele ser una solución adecuada. Aunque el paquete se inicia bajo la cuenta suplantada, los subprocesos adicionales que crea el paquete revierten a la cuenta utilizada por el proceso que inició el paquete. Estos subprocesos incluyen los utilizados por el flujo de datos para cargar y guardar datos. Por consiguiente, la propia cuenta de proceso necesita tener permisos para la mayoría de los recursos externos utilizados por el paquete.
Ejecutar un paquete de SSIS de forma remota llamando al Agente SQL Server
En el código de ejemplo siguiente se muestra cómo llamar al Agente SQL Server mediante programación para ejecutar un paquete en el servidor remoto. El código de ejemplo llama al procedimiento almacenado del sistema sp_start_job, que a su vez inicia un trabajo del Agente SQL Server, que se denomina RunSSISPackage y se encuentra en el equipo remoto. A continuación, el trabajo RunSSISPackage ejecuta el paquete en el equipo remoto en el que dicho trabajo se está ejecutando.
Nota
El valor devuelto del procedimiento almacenado sp_start_job indica si el procedimiento almacenado ha podido iniciar correctamente el trabajo del Agente SQL Server. El valor devuelto no indica si el paquete se ha iniciado correctamente o no.
Para obtener información sobre cómo solucionar problemas de los paquetes que se ejecutan desde trabajos del Agente SQL Server, vea el artículo de MicrosoftUn paquete SSIS no se ejecuta al llamar al paquete SSIS desde un paso de trabajo de Agente SQL Server.
Código de ejemplo
Los siguientes ejemplos de código requieren una referencia al ensamblado System.Data.
Imports System.Data
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim jobConnection As SqlConnection
Dim jobCommand As SqlCommand
Dim jobReturnValue As SqlParameter
Dim jobParameter As SqlParameter
Dim jobResult As Integer
jobConnection = New SqlConnection("Data Source=(local);Initial Catalog=msdb;Integrated Security=SSPI")
jobCommand = New SqlCommand("sp_start_job", jobConnection)
jobCommand.CommandType = CommandType.StoredProcedure
jobReturnValue = New SqlParameter("@RETURN_VALUE", SqlDbType.Int)
jobReturnValue.Direction = ParameterDirection.ReturnValue
jobCommand.Parameters.Add(jobReturnValue)
jobParameter = New SqlParameter("@job_name", SqlDbType.VarChar)
jobParameter.Direction = ParameterDirection.Input
jobCommand.Parameters.Add(jobParameter)
jobParameter.Value = "RunSSISPackage"
jobConnection.Open()
jobCommand.ExecuteNonQuery()
jobResult = DirectCast(jobCommand.Parameters("@RETURN_VALUE").Value, Integer)
jobConnection.Close()
Select Case jobResult
Case 0
Console.WriteLine("SQL Server Agent job, RunSISSPackage, started successfully.")
Case Else
Console.WriteLine("SQL Server Agent job, RunSISSPackage, failed to start.")
End Select
Console.Read()
End Sub
End Module
using System;
using System.Data;
using System.Data.SqlClient;
namespace LaunchSSISPackageAgent_CS
{
class Program
{
static void Main(string[] args)
{
SqlConnection jobConnection;
SqlCommand jobCommand;
SqlParameter jobReturnValue;
SqlParameter jobParameter;
int jobResult;
jobConnection = new SqlConnection("Data Source=(local);Initial Catalog=msdb;Integrated Security=SSPI");
jobCommand = new SqlCommand("sp_start_job", jobConnection);
jobCommand.CommandType = CommandType.StoredProcedure;
jobReturnValue = new SqlParameter("@RETURN_VALUE", SqlDbType.Int);
jobReturnValue.Direction = ParameterDirection.ReturnValue;
jobCommand.Parameters.Add(jobReturnValue);
jobParameter = new SqlParameter("@job_name", SqlDbType.VarChar);
jobParameter.Direction = ParameterDirection.Input;
jobCommand.Parameters.Add(jobParameter);
jobParameter.Value = "RunSSISPackage";
jobConnection.Open();
jobCommand.ExecuteNonQuery();
jobResult = (Int32)jobCommand.Parameters["@RETURN_VALUE"].Value;
jobConnection.Close();
switch (jobResult)
{
case 0:
Console.WriteLine("SQL Server Agent job, RunSISSPackage, started successfully.");
break;
default:
Console.WriteLine("SQL Server Agent job, RunSISSPackage, failed to start.");
break;
}
Console.Read();
}
}
}
Volver al principio
Ejecutar un paquete de SSIS de forma remota llamando a un componente o servicio remoto
En la sección anterior, la solución para ejecutar paquetes mediante programación en un equipo remoto no requiere ningún código personalizado en dicho equipo remoto. Sin embargo, quizá prefiera una solución que no confía en el Agente SQL Server para ejecutar los paquetes.
En el siguiente ejemplo se proporciona parte del código que se podría utilizar en un componente remoto o un servicio web del servidor para iniciar paquetes de Integration Services en el equipo remoto.
Código de ejemplo
Los siguientes ejemplos de código sugieren un método para crear y probar una clase remota que ejecuta un paquete de forma remota. Estos ejemplos no están completos, pero proporcionan el código que se podría utilizar como parte de una solución compilada como componente remoto o servicio web.
En los ejemplos se requiere una referencia al ensamblado Microsoft.SqlServer.ManagedDTS.
Crear la función para ejecutar el paquete de SSIS de forma remota
Un paquete de Integration Services se puede cargar directamente desde un archivo, directamente desde SQL Server o desde el Almacén de paquetes deSSIS, que administra el almacenamiento del paquete en SQL Server y en carpetas del sistema de archivos especiales. En este ejemplo, para que se admitan todas las opciones de carga disponibles, se usa el constructor Select Case o switch para seleccionar la sintaxis adecuada para iniciar el paquete y concatenar adecuadamente los argumentos de entrada.
Importante |
---|
Los métodos de la clase Application para trabajar con el almacén de paquetes de SSIS solamente admiten ".", localhost o el nombre del servidor local. No puede utilizar "(local)". |
El método LaunchPackage devuelve el resultado de ejecución del paquete como un entero en lugar de un valor DTSExecResult para que los equipos cliente no requieran una referencia a ningún ensamblado de Integration Services.
Importante |
---|
Este ejemplo no está completo, pero proporciona el código que se podría utilizar como parte de una solución compilada como componente remoto o servicio web. En el ejemplo no se incluyen el código, atributos o referencias que podrían ser necesarios para compilar y exponer un componente o servicio remoto. |
Para crear una clase remota para ejecutar mediante programación los paquetes en el servidor
Abra Visual Studio y cree un proyecto del tipo adecuado en su lenguaje de programación preferido.
En el código de ejemplo siguiente se utiliza el nombre LaunchSSISPackageService para el proyecto.
Agregue una referencia al ensamblado Microsoft.SqlServer.ManagedDTS.
Pegue el código de ejemplo en el archivo de clase.
En el ejemplo se muestra el contenido completo de la ventana de código.
Agregue el código, los atributos o las referencias que podrían ser necesarios para compilar y exponer un componente o servicio remoto.
Compile y pruebe el proyecto que incluye el código de ejemplo.
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.IO
Public Class LaunchSSISPackageService
' LaunchPackage Method Parameters:
' 1. sourceType: file, sql, dts
' 2. sourceLocation: file system folder, (none), logical folder
' 3. packageName: for file system, ".dtsx" extension is appended
Public Function LaunchPackage( _
ByVal sourceType As String, _
ByVal sourceLocation As String, _
ByVal packageName As String) As Integer 'DTSExecResult
Dim packagePath As String
Dim myPackage As Package
Dim integrationServices As New Application
' Combine path and file name.
packagePath = Path.Combine(sourceLocation, packageName)
Select Case sourceType
Case "file"
' Package is stored as a file.
' Add extension if not present.
If String.IsNullOrEmpty(Path.GetExtension(packagePath)) Then
packagePath = String.Concat(packagePath, ".dtsx")
End If
If File.Exists(packagePath) Then
myPackage = integrationServices.LoadPackage(packagePath, Nothing)
Else
Throw New ApplicationException( _
"Invalid file location: " & packagePath)
End If
Case "sql"
' Package is stored in MSDB.
' Combine logical path and package name.
If integrationServices.ExistsOnSqlServer(packagePath, ".", String.Empty, String.Empty) Then
myPackage = integrationServices.LoadFromSqlServer( _
packageName, "(local)", String.Empty, String.Empty, Nothing)
Else
Throw New ApplicationException( _
"Invalid package name or location: " & packagePath)
End If
Case "dts"
' Package is managed by SSIS Package Store.
' Default logical paths are File System and MSDB.
If integrationServices.ExistsOnDtsServer(packagePath, ".") Then
myPackage = integrationServices.LoadFromDtsServer(packagePath, "localhost", Nothing)
Else
Throw New ApplicationException( _
"Invalid package name or location: " & packagePath)
End If
Case Else
Throw New ApplicationException( _
"Invalid sourceType argument: valid values are 'file', 'sql', and 'dts'.")
End Select
Return myPackage.Execute()
End Function
End Class
using Microsoft.SqlServer.Dts.Runtime;
using System.IO;
public class LaunchSSISPackageServiceCS
{
public LaunchSSISPackageServiceCS()
{
}
// LaunchPackage Method Parameters:
// 1. sourceType: file, sql, dts
// 2. sourceLocation: file system folder, (none), logical folder
// 3. packageName: for file system, ".dtsx" extension is appended
public int LaunchPackage(string sourceType, string sourceLocation, string packageName)
{
string packagePath;
Package myPackage;
Application integrationServices = new Application();
// Combine path and file name.
packagePath = Path.Combine(sourceLocation, packageName);
switch(sourceType)
{
case "file":
// Package is stored as a file.
// Add extension if not present.
if (String.IsNullOrEmpty(Path.GetExtension(packagePath)))
{
packagePath = String.Concat(packagePath, ".dtsx");
}
if (File.Exists(packagePath))
{
myPackage = integrationServices.LoadPackage(packagePath, null);
}
else
{
throw new ApplicationException("Invalid file location: "+packagePath);
}
break;
case "sql":
// Package is stored in MSDB.
// Combine logical path and package name.
if (integrationServices.ExistsOnSqlServer(packagePath, ".", String.Empty, String.Empty))
{
myPackage = integrationServices.LoadFromSqlServer(packageName, "(local)", String.Empty, String.Empty, null);
}
else
{
throw new ApplicationException("Invalid package name or location: "+packagePath);
}
break;
case "dts":
// Package is managed by SSIS Package Store.
// Default logical paths are File System and MSDB.
if (integrationServices.ExistsOnDtsServer(packagePath, "."))
{
myPackage = integrationServices.LoadFromDtsServer(packagePath, "localhost", null);
}
else
{
throw new ApplicationException("Invalid package name or location: "+packagePath);
}
break;
default:
throw new ApplicationException("Invalid sourceType argument: valid values are 'file', 'sql', and 'dts'.");
}
return (Int32)myPackage.Execute();
}
}
Llamar a la función para ejecutar el paquete de SSIS de forma remota
La aplicación de consola del ejemplo siguiente utiliza el componente o servicio remoto para ejecutar un paquete.
El método LaunchPackage de la clase remota devuelve el resultado de ejecución del paquete como un entero en lugar de un valor DTSExecResult para que los equipos cliente no requieran una referencia a ningún ensamblado de Integration Services. En el ejemplo se crea una enumeración privada cuyos valores reflejan los valores DTSExecResult para notificar los resultados de ejecución.
Para crear una aplicación de consola para probar la clase remota
En Visual Studio, cree una nueva aplicación de consola mediante su lenguaje de programación preferido.
En el código de ejemplo se utiliza el nombre LaunchSSISPackageTest para el proyecto.
Agregue una referencia al ensamblado de proxy local que representa el componente o servicio remoto. Si es necesario, ajuste la declaración de variable en el código de ejemplo para el nombre que asigna al objeto proxy.
Pegue el código de ejemplo de la rutina Main y la enumeración privada en el código.
En el ejemplo se muestra el contenido completo de la ventana de código.
Modifique la línea de código que llama al método LaunchPackage para proporcionar un conjunto de valores válidos para los argumentos de entrada que señalan a un paquete existente.
Por ejemplo, si package1.dtsx está almacenado en el servidor en C:\My Packages, pase "file" como el valor de sourceType, "C:\My Packages" como el valor de sourceLocation y "package1" (sin la extensión) como el valor de packageName.
Module LaunchSSISPackageTest
Sub Main()
Dim launchPackageService As New LaunchSSISPackageService.LaunchSSISPackageService
Dim packageResult As Integer
Try
packageResult = launchPackageService.LaunchPackage("sql", String.Empty, "SimpleTestPackage")
Catch ex As Exception
Console.WriteLine("The following exception occurred: " & ex.Message)
End Try
Console.WriteLine(CType(packageResult, PackageExecutionResult).ToString)
Console.ReadKey()
End Sub
Private Enum PackageExecutionResult
PackageSucceeded
PackageFailed
PackageCompleted
PackageWasCancelled
End Enum
End Module
using System;
namespace LaunchSSISPackageSvcTestCS
{
class Program
{
static void Main(string[] args)
{
LaunchSSISPackageServiceCS.LaunchSSISPackageServiceCS launchPackageService = new LaunchSSISPackageServiceCS.LaunchSSISPackageServiceCS();
int packageResult = 0;
try
{
packageResult = launchPackageService.LaunchPackage("sql", String.Empty, "SimpleTestPackage");
}
catch (Exception ex)
{
Console.WriteLine("The following exception occurred: " + ex.Message);
}
Console.WriteLine(((PackageExecutionResult)packageResult).ToString());
Console.ReadKey();
}
private enum PackageExecutionResult
{
PackageSucceeded,
PackageFailed,
PackageCompleted,
PackageWasCancelled
};
}
}
Volver al principio
Recursos externos
- Vídeo Cómo automatizar la ejecución de paquetes usando el Agente SQL Server (vídeo de SQL Server), en technet.microsoft.com
|