在远程计算机上以编程方式运行 SSIS 包

如果客户端(本地)计算机或者未安装 Integration Services,或者无权访问包所要求的所有资源,则您必须启动该包以便该包在存储它的远程计算机上运行。您必须执行其他步骤以便确保该包运行在远程计算机上,因为某个包与启动该包的应用程序运行在同一台计算机上。因此,如果直接从本地计算机上的应用程序运行某一远程包,则该包将从本地计算机上加载并运行。因为本地计算机或者未安装 Integration Services,或者无权访问该包所要求的所有资源,所以,该包将不会成功运行。

注意注意

客户端计算机可能未安装 Integration Services,因为您的 SQL Server 许可条款可能不允许您在其他计算机上安装 Integration Services。(Integration Services 是服务器组件,不可再分发至客户端计算机。)但是,如果本地计算机安装了 Integration Services 并且您有权访问该包所要求的所有资源,则可以使用本地计算机运行远程包。有关详细信息,请参阅以编程方式在本地计算机中运行 SSIS 包

若要在远程计算机上启动该包,可以调用以下程序之一:

  • SQL Server 代理。

  • 在远程计算机上运行的其他应用程序、组件或 Web 服务。

本主题的内容

  • 远程计算机的必备条件

  • 通过调用 SQL Server 代理远程运行包

  • 通过调用远程组件或服务远程运行包

远程计算机的必备条件

您必须确保在远程计算机上运行包的进程具有所需权限。此进程要求所具备的权限不仅能够启动该包,而且能够查找并打开该包使用的所有资源。默认权限通常不足够,尤其是在基于 Web 的解决方案中。有关权限、身份验证和授权的全面讨论已超出了本主题的范围。

模拟其他帐户运行包通常不是成功的解决方案。尽管包基于模拟的帐户启动,但由该包创建的其他线程将恢复为启动了该包的进程使用的帐户。这些线程包括数据流用于加载和保存数据的线程。因此,进程帐户本身需要针对该包使用的大多数外部资源的权限。

通过调用 SQL Server 代理远程运行 SSIS 包

下面的示例代码演示如何以编程方式调用 SQL Server 代理以便在远程计算机上运行包。该代码示例调用系统存储过程 sp_start_job,而该存储过程又启动名为 RunSSISPackage 并且位于远程计算机上的 SQL Server 代理作业。然后,RunSSISPackage 作业在该作业本身正在其中运行的远程计算机上运行包。

注意注意

sp_start_job 存储过程的返回值指示该存储过程是否已能够成功启动 SQL Server 代理作业。此返回值不指示该包成功还是失败。

有关对从 SQL Server 代理作业运行的包进行故障排除的信息,请参阅 Microsoft 文章 An SSIS package does not run when you call the SSIS package from a SQL Server Agent job step(从 SQL Server 代理作业步骤调用 SSIS 包时 SSIS 包不运行)。

示例代码

下面的代码示例需要引用 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();
    }
  }
}

返回页首

通过调用远程组件或服务远程运行 SSIS 包

在前面的部分中,以编程方式在远程计算机上运行包的解决方案不需要远程计算机上的任何自定义代码。但是,您可能更倾向于不依赖 SQL Server 代理来运行包的解决方案。

下面的示例提供可在服务器上的远程组件或 Web 服务中用来启动远程计算机上的 Integration Services 包的部分代码。

示例代码

下面的代码示例建议一个方法,以便创建和测试远程运行包的远程类。这些示例并不完整,但提供的代码可用作作为远程组件或 Web 服务生成的解决方案的一部分。

这些示例需要引用 Microsoft.SqlServer.ManagedDTS 程序集。

创建函数以便远程运行 SSIS 包

Integration Services 包可从文件或 SQL Server 直接加载,也可以从 SSIS 包存储加载,该存储在 SQL Server 和特殊文件系统文件夹中管理包存储。为了支持所有可用加载选项,此示例使用 Select Case 或 switch 构造来选择启动包所用的相应语法,并相应地连接输入参数。

重要说明重要提示

Application 类中用于处理 SSIS 包存储的方法只支持“.”、localhost 或本地服务器的服务器名称。不能使用“(local)”。

LaunchPackage 方法返回的包执行结果为整数形式,而不是 DTSExecResult 值,以便客户端计算机不需要引用任何 Integration Services 程序集。

重要说明重要提示

此示例并不完整,但提供的代码可用作作为远程组件或 Web 服务生成的解决方案的一部分。此示例并不包括生成和公开远程组件或服务可能需要的代码、属性或引用。

以编程方式创建远程类以在服务器上运行包

  1. 打开 Visual Studio 并使用首选的编程语言创建相应类型的项目。

    下面的示例代码将名称 LaunchSSISPackageService 用于该项目。

  2. 添加对 Microsoft.SqlServer.ManagedDTS 程序集的引用。

  3. 将示例代码粘贴到类文件中。

    该示例显示了代码窗口的全部内容。

  4. 添加生成和公开远程组件或服务可能需要的代码、属性或引用。

  5. 生成和测试包括示例代码的项目。

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();

  }

}

调用函数以便远程运行 SSIS 包

下面的示例控制台应用程序使用远程组件或服务来运行包。

远程类的 LaunchPackage 方法返回的包执行结果为整数形式,而不是 DTSExecResult 值,以便客户端计算机不需要引用任何 Integration Services 程序集。该示例创建私有枚举,该枚举的值镜像 DTSExecResult 值,以报告执行结果。

创建用于测试远程类的控制台应用程序

  1. 在 Visual Studio 中,使用首选的编程语言创建一个新的控制台应用程序。

    示例代码将该项目命名为 LaunchSSISPackageTest。

  2. 添加对表示远程组件或服务的本地代理程序集的引用。如有必要,可调整示例代码中分配给代理对象的名称的变量声明。

  3. 将主例程和私有枚举的示例代码粘贴到代码中。

    该示例显示了代码窗口的全部内容。

  4. 编辑调用 LaunchPackage 方法的代码行,为输入参数提供一组指向现有包的有效值。

    例如,如果 package1.dtsx 存储在服务器的 C:\My Packages 中,则传递“file”作为 sourceType 的值,“C:\My Packages”作为 sourceLocation 的值,以及“package1”(不带扩展名)作为 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
    };

  }
}

返回页首

外部资源

Integration Services 图标(小) 使 Integration Services 保持最新

若要从 Microsoft 获得最新的下载内容、文章、示例和视频,以及从社区获得所选解决方案,请访问 MSDN 上的 Integration Services 页:


若要获得有关这些更新的自动通知,请订阅该页上提供的 RSS 源。