Загрузка выхода локального пакета
Клиентские приложения могут считывать выходные данные пакетов служб Integration Services при сохранении выходных данных в местах назначения SQL Server с помощью ADO.NET или при сохранении выходных данных в месте назначения неструктурированного файла с помощью классов в пространстве имен 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.
Description
В этой процедуре демонстрируется, как разработать на управляемом коде клиентское приложение, которое загружает выход пакета с назначением DataReader непосредственно из памяти. Описанные здесь шаги демонстрируются в следующем образце кода.
Загрузка данных с выхода пакета в клиентское приложение
В пакете настройте назначение DataReader для получения выхода, который необходимо считать в клиентском приложении. Дайте назначению DataReader описательное имя, поскольку оно понадобится в дальнейшем для использования в клиентском приложении. Запомните имя назначения DataReader.
В проекте разработки задайте ссылку на
Microsoft.SqlServer.Dts.DtsClient
пространство имен, найдя сборку Microsoft.SqlServer.Dts.DtsClient.dll. По умолчанию эта сборка устанавливается в C:\Program Files\Microsoft SQL Server\100\DTS\Binn. Импортируйте пространство имен в код с помощью инструкции C#Using
или Visual BasicImports
.В коде создайте объект типа
DtsClient.DtsConnection
с строка подключения, который содержит параметры командной строки, необходимые dtexec.exe для запуска пакета. Дополнительные сведения см. в статье dtexec Utility. Затем откройте соединение с помощью этой строки подключения. Можно также использовать программу dtexecui для создания необходимой строки подключения в визуальном режиме.Примечание.
В образце кода демонстрируется загрузка пакета из файловой системы с использованием синтаксиса
/FILE <path and filename>
. Однако пакет можно также загрузить из базы данных MSDB с помощью/SQL <package name>
синтаксиса или из хранилища пакетов служб Integration Services с помощью синтаксиса/DTS \<folder name>\<package name>
.Создайте объект типа
DtsClient.DtsCommand
, использующий ранее созданный объектDtsConnection
, и присвойте его свойствуCommandText
в качестве значения имя назначения DataReader в пакете. Затем вызовите методExecuteReader
командного объекта, чтобы загрузить результаты пакета в новое назначение DataReader.При необходимости можно косвенно параметризовать выход пакета с использованием коллекции объектов
DtsDataParameter
для объектаDtsCommand
, чтобы передать значения переменным, определенным в пакете. В рамках пакета можно использовать эти переменные в качестве параметров запроса или в выражениях для воздействия на результаты, возвращаемые в назначение DataReader. Эти переменные необходимо определить в пакете в пространстве имен DtsClient , прежде чем использовать их сDtsDataParameter
объектом из клиентского приложения. (Может потребоваться щелкнуть Нажмите кнопку панели инструментов "Столбцы переменных" в окне "Переменные" , чтобы отобразить столбец пространства имен.) В клиентском коде при добавленииDtsDataParameter
Parameters
DtsCommand
в коллекцию элементов опустите ссылку на пространство имен DtsClient из имени переменной. Например:command.Parameters.Add(new DtsDataParameter("MyVariable", 1));
Вызовите метод
Read
назначения DataReader повторно по мере необходимости для прохождения цикла по строкам выходных данных. Используйте эти данные или сохраните их для дальнейшего использования в клиентском приложении.Внимание
Метод
Read
в этой реализации назначения DataReader возвращает значениеtrue
еще раз после считывания последней строки данных. Возникают сложности с использованием обычного кода, реализующего цикл по назначению DataReader, пока методRead
возвращает значениеtrue
. Если пользовательским кодом предпринимается попытка закрыть назначение DataReader или соединение после считывания ожидаемого количества строк без дополнительного итогового вызова методаRead
, будет выдано необработанное исключение. Однако если код пытается считывать данные об этой окончательной итерации через цикл, когдаRead
по-прежнему возвращаетсяtrue
, но последняя строка была передана, код вызовет необработанноеApplicationException
сообщение", "SSIS IDataReader прошло конец набора результатов". Это поведение отличается от других реализаций DataReader. Поэтому при использовании цикла для считывания строк в назначении DataReader, когда методRead
возвращает значениеtrue
, необходимо написать код для захвата, тестирования и отмены ожидаемого исключенияApplicationException
в ходе последнего успешного вызова методаRead
. Либо, если заранее известно число ожидаемых строк, можно обработать строки, а затем вызвать методRead
еще раз перед закрытием назначения DataReader и соединения.Вызовите метод
Dispose
объектаDtsCommand
. Это особенно важно, если были использованы какие-либо из объектовDtsDataParameter
.Закройте назначение DataReader и объекты соединения.
Пример
В следующем примере выполняется пакет, который вычисляет единственное статистическое значение и сохраняет его в назначение DataReader, а затем считывает значение из DataReader и отображает его в текстовом поле в форме Windows.
Использование параметров не требуется при загрузке выхода пакета в клиентское приложение. Если вы не хотите использовать параметр, можно опустить использование переменной в пространстве имен DtsClient и опустить код, использующий DtsDataParameter
объект.
Создание тестового пакета
Создайте новый пакет служб Integration Services. В образце кода в качестве имени пакета используется «DtsClientWParamPkg.dtsx».
Добавьте переменную типа String в пространство имен DtsClient. В образце кода в качестве имени переменной используется «Country». (Может понадобиться нажать кнопку панели инструментов Выбор столбцов переменных в окне Переменные, чтобы отобразить столбец Namespace.)
Добавьте диспетчер соединений OLE DB, который подключается к образцу базы данных AdventureWorks2012.
Добавьте задачу потока данных в пакет и переключитесь в область конструктора потока данных.
Добавьте источник OLE DB в поток данных и настройте его для использования ранее созданного диспетчера соединений OLE DB, затем выполните следующую команду SQL:
SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?
Щелкните
Parameters
и в диалоговом окне "Задать параметры запроса" сопоставите один входной параметр в запросе, Parameter0, с переменной DtsClient::Country.Добавьте преобразование «Статистическая обработка» в поток данных и соедините выход источника OLE DB с этим преобразованием. Откройте редактор преобразования агрегата и настройте его для выполнения операции "Подсчет всех" для всех входных столбцов (*) и вывода агрегированного значения с псевдонимом CustomerCount.
Добавьте назначение DataReader в поток данных и соедините выход преобразования «Статистическая обработка» с назначением DataReader. В образце кода в качестве имени назначения DataReader используется «DataReaderDest». Укажите единственный доступный входной столбец, CustomerCount, в качестве назначения.
Сохраните пакет. Тестовое приложение, которое создается далее, выполнит пакет и извлечет его выход непосредственно из памяти.
Создание тестового приложения
Создайте новое приложение Windows Forms.
Добавьте ссылку на
Microsoft.SqlServer.Dts.DtsClient
пространство имен, перейдя к сборке того же имени в %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn.Скопируйте и вставьте следующий образец кода в программный модуль формы.
Измените значение переменной
dtexecArgs
по мере необходимости, чтобы она содержала параметры командной строки, необходимые dtexec.exe для запуска пакета. В образце кода пакет загружается из файловой системы.Измените значение переменной
dataReaderName
по мере необходимости, чтобы она содержала имя назначения DataReader в пакете.Поместите в форму кнопку и текстовое поле. Пример кода используется
btnRun
в качестве имени кнопки иtxtResults
в качестве имени текстового поля.Запустите приложение и нажмите кнопку. После небольшой паузы, связанной с выполнением пакета, статистическое значение, вычисленное пакетом (количество клиентов в Канаде), должно отобразиться в текстовом поле формы.
Пример кода
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 на сайте MSDN:
Посетить страницу «Службы Integration Services» на сайте MSDN
Чтобы получать автоматические уведомления об этих обновлениях, подпишитесь на RSS-каналы, предлагаемые на этой странице.
См. также
Общие сведения о различиях между локальной и удаленной загрузкой изапуском локального пакета программнымспособом загрузки и запуска удаленного пакета