Загрузка выхода пакета в другую программу

Клиентские приложения могут читать выходные данные пакетов служб Integration Services с помощью следующих параметров.

  • ADO.NET, когда выходные данные сохранены в назначения SQL Server.

  • Классы в пространстве имен System.IO, когда выходные данные сохранены в неструктурированный файл назначения.

Кроме того, клиентское приложение может считывать выход пакета непосредственно из памяти, без необходимости промежуточного шага для сохранения данных.

Это можно сделать с помощью пространства имен Microsoft.SqlServer.Dts.DtsClient, содержащего специализированные реализации интерфейсов IDbConnection, IDbCommand и IDbDataParameter из пространства имен System.Data. Можно найти это пространство имен в сборке Microsoft.SqlServer.Dts.DtsClient.dll, установленной по умолчанию в папку %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn.

ПримечаниеПримечание

Для процедуры, описанной в этом разделе, необходимо, чтобы свойству DelayValidation задачи потока данных и любых родительских объектов было присвоено значение по умолчанию False.

Подразделы данного раздела

  • Загрузка выходных данных пакета напрямую из памяти

  • Пример

Загрузка выходных данных пакета напрямую из памяти

В этой процедуре демонстрируется, как разработать на управляемом коде клиентское приложение, которое загружает выход пакета с назначением DataReader непосредственно из памяти. В разделе, следующим за этой процедурой, дан образец кода для показа обобщенных шагов процедуры.

Загрузка выходных данных пакета в клиентское приложение из памяти

  1. В потоке данных пакета настройте назначение DataReader для получения выхода, который необходимо считать в клиентском приложении. Дайте назначению DataReader описательное имя, поскольку оно понадобится в дальнейшем для использования в клиентском приложении. Запомните имя назначения DataReader.

  2. В проекте разработки создайте ссылку на пространство имен Microsoft.SqlServer.Dts.DtsClient, указав местоположение сборки Microsoft.SqlServer.Dts.DtsClient.dll. По умолчанию эта сборка устанавливается в папку C:\Program Files\Microsoft SQL Server\100\DTS\Binn. Импортируйте это пространство имен с помощью инструкции using языка C# или инструкции Imports языка Visual Basic.

  3. В коде создайте объект типа DtsClient.DtsConnection со строкой соединения, содержащей параметры командной строки, которые необходимы для dtexec.exe, чтобы выполнить пакет. Дополнительные сведения см. в разделе Программа dtexec (средства служб SSIS). Можно также использовать программу dtexecui для создания необходимой строки соединения в визуальном режиме.

    ПримечаниеПримечание

    В образце кода после этой процедуры загружается пакет из файловой системы с использованием синтаксиса /FILE <path and filename>. Однако можно также загрузить пакет из базы данных MSDB с помощью синтаксиса /SQL <package name> или из хранилища пакетов служб Integration Services с помощью синтаксиса /DTS \<folder name>\<package name>.

  4. Откройте соединение с помощью этой строки соединения.

  5. Создайте объект типа DtsClient.DtsCommand, использующий ранее созданный объект DtsConnection как соединение. Установите для командного свойства CommandText значение имени назначения DataReader в пакете. Затем вызовите метод ExecuteReader командного объекта, чтобы загрузить результаты пакета в новое назначение DataReader.

  6. При необходимости можно косвенно параметризовать выход пакета с использованием коллекции объектов DtsDataParameter для объекта DtsCommand, чтобы передать значения переменным, определенным в пакете. В рамках пакета можно использовать эти переменные в качестве параметров запроса или в выражениях для воздействия на результаты, возвращаемые в назначение DataReader. Необходимо определить эти переменные в пакете в пространстве имен DtsClient, прежде чем можно будет использовать их с объектом DtsDataParameter из клиентского приложения. (Может понадобиться нажать кнопку панели инструментов Выбор столбцов переменных в окне Переменные, чтобы отобразить столбец Namespace.) В клиентском коде при добавлении параметра DtsDataParameter в коллекцию Parameters объекта DtsCommand опустите ссылку на пространство имен DtsClient в имени переменной. Например,

    command.Parameters.Add(new DtsDataParameter("MyVariable", 1));
    
  7. Вызовите метод Read назначения DataReader повторно по мере необходимости для прохождения цикла по строкам выходных данных. Используйте эти данные или сохраните их для дальнейшего использования в клиентском приложении.

    Важное примечаниеВажно!

    Метод Read в этой реализации назначения DataReader возвращает значение true еще раз после считывания последней строки данных. Возникают сложности с использованием обычного кода, реализующего цикл по назначению DataReader, пока метод Read возвращает значение true. Если пользовательским кодом предпринимается попытка закрыть назначение DataReader или соединение после считывания ожидаемого количества строк без дополнительного итогового вызова метода Read, будет выдано необработанное исключение. Однако если в коде предпринята попытка чтения данных в ходе этой последней итерации по циклу, метод Read все так же возвращает значение true, но после передачи последней строки кодом будет выдано необработанное исключение ApplicationException с сообщением, «Объект IDataReader служб SSIS находится за пределами результирующего набора». Это поведение отличается от остальных реализаций назначения DataReader. Поэтому при использовании цикла для считывания строк в назначении DataReader, когда метод Read возвращает значение true, необходимо написать код для захвата, тестирования и отмены ожидаемого исключения ApplicationException в ходе последнего успешного вызова метода Read. Либо, если заранее известно число ожидаемых строк, можно обработать строки, а затем вызвать метод Read еще раз перед закрытием назначения DataReader и соединения.

  8. Вызовите метод Dispose объекта DtsCommand. Это особенно важно, если были использованы какие-либо из объектов DtsDataParameter.

  9. Закройте назначение DataReader и объекты соединения.

Примеры

В следующем примере выполняется пакет, который вычисляет единственное статистическое значение и сохраняет его в назначение DataReader, а затем считывает значение из DataReader и отображает его в текстовом поле в форме Windows.

Использование параметров не требуется при загрузке выхода пакета в клиентское приложение. Если нет необходимости использовать параметр, можно опустить переменную в пространстве имен DtsClient, а также код, использующий объект DtsDataParameter.

Создание тестового пакета

  1. Создайте новый пакет служб Integration Services. В образце кода в качестве имени пакета используется «DtsClientWParamPkg.dtsx».

  2. Добавьте переменную типа String в пространство имен DtsClient. В образце кода в качестве имени переменной используется «Country». (Может понадобиться нажать кнопку панели инструментов Выбор столбцов переменных в окне Переменные, чтобы отобразить столбец Namespace.)

  3. Добавьте диспетчер соединений OLE DB, соединяющийся с образцом базы данных База данных AdventureWorks2008R2.

  4. Добавьте задачу потока данных в пакет и переключитесь в область конструктора потока данных.

  5. Добавьте источник OLE DB в поток данных и настройте его для использования ранее созданного диспетчера соединений OLE DB, затем выполните следующую команду SQL:

    SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?
    
  6. Нажмите кнопку Параметры и в диалоговом окне Установка параметров запроса сопоставьте единственный входной параметр в запросе, Parameter0, с переменной DtsClient::Country.

  7. Добавьте преобразование «Статистическая обработка» в поток данных и соедините выход источника OLE DB с этим преобразованием. Откройте редактор преобразования «Статистическая обработка» и настройте его для выполнения операции «Count all» для всех входных столбцов (*) и для вывода статистического значения с псевдонимом CustomerCount.

  8. Добавьте назначение DataReader в поток данных и соедините выход преобразования «Статистическая обработка» с назначением DataReader. В образце кода в качестве имени назначения DataReader используется «DataReaderDest». Укажите единственный доступный входной столбец, CustomerCount, в качестве назначения.

  9. Сохраните пакет. Тестовое приложение, которое создается далее, выполнит пакет и извлечет его выход непосредственно из памяти.

Создание тестового приложения

  1. Создайте новое приложение Windows Forms.

  2. Добавьте ссылку на пространство имен Microsoft.SqlServer.Dts.DtsClient, указав местоположение сборки с тем же именем в папке %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn.

  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

Чтобы загружать новейшую документацию, статьи, образцы и видеоматериалы от корпорации Майкрософт, а также лучшие решения от участников сообщества, посетите страницу служб Integration Services на сайтах MSDN или TechNet:

Чтобы получать автоматические уведомления об этих обновлениях, подпишитесь на RSS-каналы, предлагаемые на этой странице.