共用方式為


載入本機封裝的輸出

使用 ADO.NET 將輸出儲存到 SQL Server 目的地時,或使用 System.IO 命名空間將輸出儲存到一般檔案目的地時,用戶端應用程式可讀取 Integration Services 套件的輸出。 但用戶端應用程式也可直接從記憶體讀取封裝的輸出,而無須在程序中間執行保存資料的步驟。 此解決方案的關鍵是Microsoft.SqlServer.Dts.DtsClient命名空間,其中包含 System.Data 命名空間中IDbConnectionIDbCommandIDbDataParameter 介面的特製化實作。 預設會在 %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn 中安裝 Microsoft.SqlServer.Dts.DtsClient.dll 組件。

注意

本主題所述之程序需要將資料流程工作與任何父物件的 DelayValidation 屬性,設定成其預設值 False

描述

這個程序示範如何以 Managed 程式碼開發用戶端應用程式,這個程式碼使用 DataReader 目的地直接從記憶體載入封裝的輸出。 這裡所摘要的步驟將在接下來的程式碼範例中示範。

將資料封裝輸出載入用戶端應用程式

  1. 在封裝中,設定 DataReader 目的地以接收您要讀到用戶端應用程式中的輸出。 給 DataReader 目的地一個描述性名稱,因為您稍後將在用戶端應用程式中使用這個名稱。 記下 DataReader 目的地的名稱。

  2. 在開發專案中,藉由尋找元件Microsoft.SqlServer.Dts.DtsClient.dll 來設定命名空間的參考Microsoft.SqlServer.Dts.DtsClient。 此組件預設安裝在 C:\Program Files\Microsoft SQL Server\100\DTS\Binn 中。 使用 C# Using 或 Visual Basic Imports 語句將命名空間匯入您的程式代碼。

  3. 在您的程式代碼中,使用包含執行封裝dtexec.exe所需之命令行參數的 連接字串,建立 型DtsClient.DtsConnection別的物件。 如需詳細資訊,請參閱 dtexec Utility。 然後使用此連接字串開啟連接。 您也可以使用 dtexecui 公用程式,以視覺化方式建立所需的連接字串。

    注意

    範例程式碼透過使用 /FILE <path and filename> 語法示範從檔案系統載入封裝。 不過,您也可以使用 /SQL <package name> 語法從 MSDB 資料庫載入套件,或是使用 /DTS \<folder name>\<package name> 語法從 Integration Services 套件存放區載入。

  4. 建立型 DtsClient.DtsCommand 別的物件,該物件會使用先前建立 DtsConnection 的 ,並將其 CommandText 屬性設定為封裝中的 DataReader 目的地名稱。 然後呼叫 ExecuteReader 命令物件的 方法,將封裝結果載入新的 DataReader。

  5. 您可以選擇性地使用 物件上的 DtsCommand 物件集合DtsDataParameter,將值傳遞至封裝中定義的變數,間接參數化封裝的輸出。 您可以在封裝中使用這些變數做為查詢參數,或在運算式中加以運用,藉此影響傳回 DataReader 目的地的結果。 您必須先在 DtsClient 命名空間的封裝中定義這些變數,才能與用戶端應用程式中的 物件搭配DtsDataParameter使用。 (您可能需要按兩下在 [變數] 視窗中選擇 [變數數據行] 工具列按鈕,以顯示 [命名空間] 數據行。在用戶端程式代碼中,當您將 加入 DtsDataParameterParametersDtsCommand集合時,請省略變數名稱中的 DtsClient 命名空間參考。 例如:

    command.Parameters.Add(new DtsDataParameter("MyVariable", 1));
    
  6. Read視需要重複呼叫 DataReader 的 方法,以迴圈查看輸出數據的數據列。 在用戶端應用程式中使用資料或是儲存資料以供稍後使用。

    重要

    DataReader Read 這個實作的 方法會在讀取最後一個數據列之後再傳回 true 一次。 如此一來,在傳回 trueRead,很難使用迴圈處理 DataReader 的一般程序代碼。 如果您的程式代碼在讀取預期的數據列數目之後嘗試關閉 DataReader 或連接,而不需要對 方法進行額外的最終呼叫 Read ,程式代碼就會引發未處理的例外狀況。 不過,如果您的程式代碼嘗試透過迴圈讀取此最後反覆專案上的數據,當仍然傳回true但最後一個數據列已傳遞時Read,程式代碼會引發未處理的ApplicationException訊息:「SSIS IDataReader 已超過結果集的結尾」。此行為與其他 DataReader 實作的行為不同。 因此,當使用循環在傳回 時Read讀取 DataReader 中的數據列時,您需要撰寫程式代碼來攔截、測試及捨棄此方法最後一次成功呼叫Read時所預期的ApplicationExceptiontrue 或者,如果您事先知道預期的數據列數目,您可以處理數據列,然後在關閉 DataReader 和連接之前再呼叫 Read 方法一次。

  7. Dispose呼叫 物件的方法DtsCommand。 如果您使用任何 DtsDataParameter 物件,這特別重要。

  8. 關閉 DataReader 和連接物件。

範例

下列範例執行的封裝,會計算單一彙總值並將值儲存到 DataReader 目的地,然後從 DataReader 讀取這個值,並在 Windows Form 的文字方塊中顯示值。

將封裝的輸出載入用戶端應用程式時,不需要使用參數。 如果您不想使用 參數,可以省略 DtsClient 命名空間中的變數使用,並省略使用 DtsDataParameter 對象的程序代碼。

建立測試封裝

  1. 建立新的 Integration Services 套件。 範例程式碼使用 "DtsClientWParamPkg.dtsx" 做為封裝的名稱。

  2. 在 DtsClient 命名空間中加入 String 類型的變數。 範例程式碼使用 Country 做為變數的名稱 (您可能需要按一下 [變數] 視窗中的 [選擇變數資料行] 工具列按鈕,才會顯示 [命名空間] 資料行)。

  3. 新增連線至 AdventureWorks2012 範例資料庫的 OLE DB 連接管理員。

  4. 將資料流程工作加入封裝,並切換至資料流程設計介面。

  5. 將 OLE DB 來源加入資料流程並將它設定成使用先前建立的 OLE DB 連接管理員,並加入下列 SQL 命令:

    SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?
    
  6. 按兩下 Parameters ,然後在 [ 設定查詢參數 ] 對話框中,將查詢中的單一輸入參數Parameter0對應至 DtsClient::Country 變數。

  7. 將彙總轉換加入資料流程,然後將 OLE DB 來源的輸出連接到轉換。 開啟 [匯總轉換編輯器],並將其設定為在所有輸入數據行上執行「計算全部計數」作業 , 並使用 alias CustomerCount 輸出匯總的值。

  8. 將 DataReader 目的地加入資料流程,然後將彙總轉換的輸出連接到 DataReader 目的地。 範例程式碼使用 "DataReaderDest" 做為 DataReader 的名稱。 為目的地選取單一可用的輸入資料行 CustomerCount。

  9. 儲存封裝。 建立的測試應用程式將執行封裝並直接從記憶體擷取其輸出。

建立測試應用程式

  1. 建立新的 Windows Form 應用程式。

  2. 流覽至 %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn相同名稱的元件,以新增命名空間的參考Microsoft.SqlServer.Dts.DtsClient

  3. 將下列範例程式碼複製並貼入表單的程式碼模組。

  4. 視需要修改變量的值dtexecArgs,使其包含執行封裝dtexec.exe所需的命令行參數。 範例程式碼會從檔案系統載入封裝。

  5. 視需要修改變量的值 dataReaderName ,使其包含封裝中 DataReader 目的地的名稱。

  6. 在表單上放置按鈕與文字方塊。 範例程式代碼會使用 btnRun 作為按鈕的名稱,以及 txtResults 做為文本框的名稱。

  7. 執行應用程式,然後按一下按鈕。 在簡短地暫停封裝執行之後,您應該會在表單的文字方塊中,看到封裝計算的彙總值 (加拿大的客戶計數)。

範例程式碼

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;

    }
  }
}

Integration Services 圖示 (小型) 使用 Integration Services 保持最新狀態
如需來自Microsoft的最新下載、文章、範例和影片,以及來自社群的所選解決方案,請流覽 MSDN 上的 Integration Services 頁面:

流覽 MSDN 上的 Integration Services 頁面

如需這些更新的自動通知,請訂閱頁面上可用的 RSS 摘要。

另請參閱

瞭解本機與遠端執行載入和執行本機套件之間的差異,以程式設計方式載入和執行遠端套件