Laden der Ausgabe eines Pakets in ein anderes Programm

Clientanwendungen können die Ausgabe von Integration Services-Paketen mit einer der folgenden Optionen lesen:

  • ADO.NET, wenn die Ausgabe in SQL Server-Zielen gespeichert wird.

  • Klassen im System.IO-Namespace, wenn die Ausgabe in einem Flatfileziel gespeichert wird.

Eine Clientanwendung kann jedoch die Ausgabe eines Pakets auch direkt aus dem Arbeitsspeicher lesen, ohne dass hierfür ein Zwischenschritt zur Speicherung der Daten erforderlich ist.

Der Schlüssel zu dieser Lösung liegt in dem Microsoft.SqlServer.Dts.DtsClient-Namespace, der spezielle Implementierungen der IDbConnection-, IDbCommand- und IDbDataParameter-Schnittstelle aus dem System.Data-Namespace enthält. Sie können diesen Namespace im %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn Ordner in der Assembly, Microsoft.SqlServer.Dts.DtsClient.dll, suchen, die installiert ist, standardmäßig finden.

HinweisHinweis

Für die in diesem Thema beschriebene Vorgehensweise muss die DelayValidation Eigenschaft des Datenflusstasks und eines der übergeordneten Objekte auf den Standardwert False festgelegt werden.

Kapitel in diesem Thema

  • So laden Sie direkt die Ausgabe eines Pakets aus dem Arbeitsspeicher

  • Beispiel

So laden Sie direkt die Ausgabe eines Pakets aus dem Arbeitsspeicher

In dieser Prozedur wird veranschaulicht, wie eine Clientanwendung in verwaltetem Code benutzt wird, um eine Clientanwendung zu entwickeln, die die Ausgabe eines Pakets mit DataReader-Inhalt direkt aus dem Arbeitsspeicher lädt. Im diesem Abschnitt verfolgt man im Anschluss am das Verfahren ein Codebeispiel, in dem die zusammengefassten Schritte der Prozedur veranschaulicht werden.

So können Sie die Ausgabe eines Pakets vom Arbeitsspeicher in eine Clientanwendung laden

  1. Konfigurieren Sie in dem Datenfluss des Pakets ein DataReader-Ziel so, dass die Ausgabe empfangen wird, die in die Clientanwendung gelesen werden soll. Geben Sie dem DataReader-Ziel einen aussagekräftigen Namen, da Sie diesen Namen später in der Clientanwendung verwenden werden. Notieren Sie sich den Namen des DataReader-Ziels.

  2. Legen Sie im Entwicklungsprojekt einen Verweis auf den Microsoft.SqlServer.Dts.DtsClient-Namespace fest, indem Sie die Microsoft.SqlServer.Dts.DtsClient.dll-Assembly auswählen. Standardmäßig ist diese Assembly im Verzeichnis C:\Programme\Microsoft SQL Server\100\DTS\Binn installiert. Importieren Sie den Namespace mithilfe der C#-Anweisung using oder der Visual BasicImports-Anweisung in den Code.

  3. Erstellen Sie in Ihrem Code ein Objekt vom Typ DtsClient.DtsConnection mit einer Verbindungszeichenfolge, die die Befehlszeilenparameter enthält, die für dtexec.exe zum Ausführen des Pakets erforderlich sind. Weitere Informationen finden Sie unter dtexec-Hilfsprogramm (SSIS-Tool). Sie können auch das dtexecui-Hilfsprogramm verwenden, um die erforderliche Verbindungszeichenfolge visuell zu erstellen.

    HinweisHinweis

    Im Beispielcode, der dieser Prozedur folgt, wird das Paket aus dem Dateisystem mit dem /FILE <path and filename>-Syntax geladen. Sie können das Paket jedoch auch aus der MSDB-Datenbank mithilfe der /SQL <package name>-Syntax oder aus dem Integration Services-Paket mithilfe der /DTS \<folder name>\<package name>-Syntax laden.

  4. Öffnen Sie dann die Verbindung mit dieser Verbindungszeichenfolge.

  5. Erstellen Sie ein Objekt von Typ DtsClient.DtsCommand, der den zuvor erstellten DtsConnection als Verbindung verwendet. Legen Sie die CommandText-Eigenschaft des Befehls im Paket auf den Namen des DataReader-Ziels fest. Rufen Sie dann die ExecuteReader-Methode des Befehlsobjekts auf, um die Paketergebnisse in ein neues DataReader-Ziel zu laden.

  6. Optional können Sie die Ausgabe des Pakets indirekt parametrisieren, indem Sie die Auflistung von DtsDataParameter-Objekten im DtsCommand-Objekt verwenden, um Werte an die in dem Paket definierten Variablen zu übergeben. Innerhalb des Pakets können Sie diese Variablen als Abfrageparameter oder in Ausdrücken verwenden, um die an das DataReader-Ziel zurückgegebenen Ergebnisse zu beeinflussen. Sie müssen diese Variablen im Paket im DtsClient-Namespace definieren, bevor Sie diese mit dem DtsDataParameter-Objekt aus einer Clientanwendung verwenden können. (Möglicherweise müssen Sie im Fenster Variablen auf die Symbolleistenschaltfläche Variablenspalten auswählen klicken, um die Spalte Namespace anzuzeigen.) Verzichten Sie im Clientcode auf den DtsClient-Namespaceverweis aus dem Variablennamen, wenn Sie der Parameters-Auflistung des DtsCommand einen DtsDataParameter hinzufügen. Beispiel:

    command.Parameters.Add(new DtsDataParameter("MyVariable", 1));
    
  7. Rufen Sie die Read-Methode des DataReader so oft wie benötigt wiederholt auf, um die Zeilen der Ausgabedaten zu durchlaufen. Verwenden Sie die Daten, oder speichern Sie die Daten zur späteren Verwendung in der Clientanwendung.

    Wichtiger HinweisWichtig

    Die Read-Methode dieser Implementierung des DataReader gibt, nachdem die letzte Zeile der Daten gelesen wurde, true noch ein weiteres Mal zurück. Daher ist es schwierig, den normalen Code zu verwenden, der den DataReader durchläuft, während von Readtrue zurückgegeben wird. Wenn der Code versucht, den DataReader oder die Verbindung nach dem Lesen der erwarteten Anzahl von Reihen zu schließen, ohne einen weiteren finalen Aufruf der Read-Methode durchzuführen, gibt der Code eine nicht behandelte Ausnahme aus. Wenn der Code jedoch versucht, die Daten bei dieser letzten Iteration durch eine Schleife zu lesen und von Read immer noch true zurückgegeben wird, die letzte Zeile jedoch übergeben wurde, gibt der Code eine nicht behandelte ApplicationException mit der folgenden Meldung aus: "Das SSIS-IDataReader-Objekt liegt hinter dem Ende des Resultsets." Dieses Verhalten unterscheidet sich von dem anderer DataReader-Implementierungen. Wenn Sie daher eine Schleife verwenden, um die Zeilen in dem DataReader zu lesen, und von Read wird true zurückgegeben, müssen Sie den Code so schreiben, dass diese erwartete ApplicationException beim letzten erfolgreichen Aufruf der Read-Methode abgefangen, getestet und verworfen wird. Sie können auch, wenn Sie die Anzahl von erwarteten Zeilen im Voraus wissen, die Zeilen verarbeiten und dann die Read-Methode ein letztes Mal aufrufen, bevor Sie den DataReader und die Verbindung schließen.

  8. Rufen Sie die Dispose-Methode des DtsCommand-Objekts auf. Dies ist besonders wichtig, wenn Sie DtsDataParameter-Objekte verwendet haben.

  9. Schließen Sie den DataReader und die Verbindungsobjekte.

Beispiel

Im folgenden Beispiel wird ein Paket ausgeführt, das einen einzelnen Aggregatwert berechnet und den Wert in einem DataReader-Ziel speichert. Dieser Wert wird dann vom DataReader gelesen und in einem Textfeld in einem Windows Form angezeigt.

Beim Laden der Ausgabe eines Pakets in einer Clientanwendung müssen keine Parameter verwendet werden. Wenn Sie keinen Parameter verwenden möchten, können Sie auf die Verwendung der Variablen im DtsClient-Namespace verzichten und den Code weglassen, der das DtsDataParameter-Objekt verwendet.

So erstellen Sie das Testpaket

  1. Erstellen Sie ein neues Integration Services-Paket. Im Beispielcode wird "DtsClientWParamPkg.dtsx" als Name des Pakets verwendet.

  2. Fügen Sie eine Variable der Typzeichenfolge im DtsClient-Namespace hinzu. Der Beispielscode verwendet "Country" als den Namen der Variablen. (Möglicherweise müssen Sie im Fenster Variablen auf die Symbolleistenschaltfläche Variablenspalten auswählen klicken, um die Spalte Namespace anzuzeigen.)

  3. Fügen Sie einen OLE DB-Verbindungs-Manager hinzu, der eine Verbindung zu der AdventureWorks2008R2-Beispieldatenbank herstellt.

  4. Fügen Sie dem Paket einen Datenflusstask hinzu, und wechseln Sie zur Datenfluss-Entwurfsoberfläche.

  5. Fügen Sie dem Datenfluss eine OLE DB-Quelle hinzu, und konfigurieren Sie sie so, dass der zuvor erstellte OLE DB-Verbindungs-Manager verwendet werden kann, den Sie vorher erstellt haben. Fügen Sie auch den folgenden SQL-Befehl hinzu:

    SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?
    
  6. Klicken Sie auf Parameter, und weisen Sie im Dialogfeld Abfrageparameter festlegen den einzelnen Eingabeparameter in der Abfrage, Parameter0, der DtsClient::Country-Variablen hinzu.

  7. Fügen Sie dem Datenfluss eine Transformation für das Aggregieren hinzu, und verbinden Sie die Ausgabe der OLE DB-Quelle mit der Transformation. Öffnen Sie den Transformations-Editor für Aggregieren, und konfigurieren Sie diesen so, dass alle Eingabespalten (*) gezählt werden und der Aggregatwert mit dem Alias "CustomerCount" ausgegeben wird.

  8. Fügen Sie dem Datenfluss ein DatenReader-Ziel hinzu, und verbinden Sie die Ausgabe der Transformation für das Aggregieren mit dem DataReader-Ziel. Im Beispielcode wird "DataReaderDest" als Name des DataReader verwendet. Wählen Sie die einzelne verfügbare Eingabespalte, CustomerCount, für das Ziel aus.

  9. Speichern Sie das Paket. Die anschließend erstellte Testanwendung führt das Paket aus und ruft seine Ausgabe direkt vom Arbeitsspeicher ab.

So erstellen Sie die Testanwendung

  1. Erstellen Sie eine neue Windows Forms-Anwendung.

  2. Fügen Sie einen Verweis zu dem Microsoft.SqlServer.Dts.DtsClient-Namespace hinzu, indem Sie zu der Assembly mit dem gleichen Namen im Verzeichnis %Programme%\Microsoft SQL Server\100\DTS\Binn navigieren.

  3. Kopieren Sie den folgenden Beispielcode, und fügen Sie ihn in das Codemodul für das Formular ein.

  4. Ändern Sie nach Bedarf den Wert der dtexecArgs-Variablen so, dass diese die Befehlszeilenparameter enthält, die für dtexec.exe zum Ausführen des Pakets erforderlich sind. Im Beispielcode wird das Paket aus dem Dateisystem geladen.

  5. Ändern Sie bei Bedarf den Wert der dataReaderName-Variablen so, dass diese den Namen des DataReader-Ziels im Paket enthält.

  6. Setzen Sie eine Schaltfläche und ein Textfeld in das Formular. Im Beispielcode wird btnRun als Name der Schaltfläche und txtResults als Name des Textfelds verwendet.

  7. Führen Sie die Anwendung aus, und klicken Sie auf die Schaltfläche. Nach einer kurzen Pause während der Ausführung des Pakets sollte der von dem Paket berechnete Aggregatwert (die Anzahl von Kunden in Kanada) im Textfeld auf dem Formular angezeigt werden.

Beispielcode

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 (kleines Symbol) Bleiben Sie mit Integration Services auf dem neuesten Stand

Die neuesten Downloads, Artikel, Beispiele und Videos von Microsoft sowie ausgewählte Lösungen aus der Community finden Sie auf der Integration Services-Seite von MSDN oder TechNet:

Abonnieren Sie die auf der Seite verfügbaren RSS-Newsfeeds, um automatische Benachrichtigungen zu diesen Aktualisierungen zu erhalten.