ローカル パッケージの出力の読み込み
クライアント アプリケーションは、ADO.NET を使用して SQL Server 変換先に出力が保存された場合、または System.IO 名前空間のクラスを使用してフラット ファイル変換先に出力が保存された場合に、Integration Services パッケージの出力を読み取ることができます。 ただし、メモリから直接、パッケージの出力を読み取ることもできます。その際、データを保持するための中間手段を必要としません。 このソリューションの鍵となるのは、Microsoft.SqlServer.Dts.DtsClient
名前空間であり、System.Data 名前空間の IDbConnection
、IDbCommand
、IDbDataParameter インターフェイスの特殊な実装が含まれています。 既定では、アセンブリ Microsoft.SqlServer.Dts.DtsClient.dll は、%ProgramFiles%\Microsoft SQL Server\100\DTS\Binn にインストールされています。
Note
このトピックで説明されている手順では、データ フロー タスクおよび親オブジェクトの DelayValidation プロパティが既定値の False に設定されている必要があります。
説明
この手順では、マネージド コードを使用して、DataReader 変換先でパッケージの出力をメモリから直接読み込むクライアント アプリケーションを開発する方法を示します。 ここにまとめた手順は、後のコード例で示します。
クライアント アプリケーションにパッケージ出力を読み込むには
パッケージで、クライアント アプリケーションに読み込む出力を受信するように DataReader 変換先を構成します。 DataReader 変換先にはわかりやすい名前を付けます。この名前は後からクライアント アプリケーションで使用します。 DataReader 変換先の名前はメモしておきます。
開発プロジェクトで、アセンブリ Microsoft.SqlServer.Dts.DtsClient.dllを検索して、
Microsoft.SqlServer.Dts.DtsClient
名前空間への参照を設定します。 既定では、このアセンブリは C:\Program Files\Microsoft SQL Server\100\DTS\Binn にインストールされます。 C#Using
または Visual BasicImports
ステートメントを使用して、名前空間をコードにインポートします。コードで、dtexec.exeがパッケージを実行するために必要なコマンド ライン パラメーターを含む接続文字列を持つ
DtsClient.DtsConnection
型のオブジェクトを作成します。 詳細については、「dtexec ユーティリティ」を参照してください。 次に、この接続文字列を使用して接続を開きます。 dtexecui ユーティリティを使用して、必要な接続文字列を視覚的に作成することもできます。注意
このサンプル コードは、
/FILE <path and filename>
構文を使用してファイル システムからパッケージを読み込む方法を示していますが、/SQL <package name>
構文を使用して MSDB データベースからパッケージを読み込んだり、/DTS \<folder name>\<package name>
構文を使用して Integration Services パッケージ ストアからパッケージを読み込むこともできます。前に作成した
DtsClient.DtsCommand
を使用するDtsConnection
という種類のオブジェクトを作成し、そのCommandText
プロパティに、パッケージ内の DataReader 変換先の名前を設定します。 次に、コマンド オブジェクトのExecuteReader
メソッドを呼び出して、パッケージの結果を新しい DataReader に読み込みます。必要に応じて、
DtsDataParameter
オブジェクトでDtsCommand
オブジェクトのコレクションを使用して、パッケージに定義された変数に値を渡すことによって、パッケージの出力を間接的にパラメーター化できます。 パッケージ内では、これらの変数をクエリ パラメーターとして、または式で使用して、DataReader 変換先に返される結果に影響を与えることができます。 これらの変数は、クライアント アプリケーションからDtsDataParameter
オブジェクトと共に使用する前に、DtsClient 名前空間のパッケージで定義する必要があります。 (をクリックする必要がある場合がありますVariables ウィンドウの [変数列ツール バー ボタンを選択して、Namespace 列を表示します。クライアント コードで、DtsCommand
のParameters
コレクションにDtsDataParameter
を追加するときに、変数名から DtsClient 名前空間参照を省略します。 次に例を示します。command.Parameters.Add(new DtsDataParameter("MyVariable", 1));
出力データの行をループするのに必要なだけ、DataReader の
Read
メソッドを繰り返し呼び出します。 クライアント アプリケーションで、データを使用するか、または後で使用するために保存します。重要
DataReader のこの実装の
Read
メソッドは、データの最後の行が読み取られた後にもう一度true
を返します。 このため、Read
がtrue
を返している間、DataReader をループする通常のコードを使用することが難しくなります。 予定した行数を読み取った後にRead
メソッドの追加の最終呼び出しがないと、コードで DataReader または接続を閉じようとした場合に、ハンドルされていない例外が発生します。 ただし、コードがループを通じてこの最後のイテレーションのデータを読み取ろうとした場合、Read
はまだtrue
を返しますが、最後の行が渡された場合、コードは "SSIS IDataReader は結果セットの末尾を超えています" というメッセージを含む未処理のApplicationException
を発生させます。この動作は、他の DataReader 実装とは異なります。 したがって、Read
がtrue
を返している間にループを使用して DataReader 内の行を最後まで読み取るようにするには、最後のApplicationException
メソッドの正常な呼び出しで予想されるこのRead
をキャッチ、テスト、および破棄するコードを記述する必要があります。 あるいは、予定の行数があらかじめわかっている場合は、行を処理してから、DataReader および接続を閉じる前にもう一度Read
メソッドを呼び出します。Dispose
オブジェクトのDtsCommand
メソッドを呼び出します。DtsDataParameter
オブジェクトを使用している場合、これは特に重要です。DataReader と接続オブジェクトを閉じます。
例
次の例では、1 つの集計値を計算してその値を DataReader 変換先に保存するパッケージを実行します。次に、この値を DataReader から読み取って、Windows フォーム上のテキスト ボックスに表示します。
パッケージの出力をクライアント アプリケーションに読み込む場合は、パラメーターを使用する必要はありません。 パラメーターを使用しない場合は、 DtsClient 名前空間内の変数の使用を省略し、 DtsDataParameter
オブジェクトを使用するコードを省略できます。
テスト パッケージを作成するには
新しい Integration Services パッケージを作成します。 サンプル コードでは、パッケージの名前として "DtsClientWParamPkg.dtsx" が使用されています。
DtsClient 名前空間に文字列型の変数を追加します。 サンプル コードでは、変数の名前として Country が使用されています ([名前空間] 列を表示するには、[変数] ウィンドウの [変数列の選択] ツール バー ボタンをクリックする必要がある場合があります)。
AdventureWorks2012 サンプル データベースに接続する OLE DB 接続マネージャーを追加します。
データ フロー タスクをパッケージに追加し、[データ フロー] デザイン画面に切り替えます。
OLE DB ソースをデータ フローに追加し、前に作成した OLE DB 接続マネージャーを使用するように構成して、次の SQL コマンドを実行します。
SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?
Parameters
をクリックし、[クエリ パラメーターの 設定] ダイアログ ボックスで、クエリパラメーター 0 の単一の入力パラメーターを DtsClient::Country 変数にマップします。データ フローに集計変換を追加し、OLE DB ソースの出力を変換に接続します。 集計変換エディターを開き、すべての入力列 (*) に対して "すべてカウント" 操作を実行し、エイリアス CustomerCount を使用して集計値を出力するように構成します。
データ フローに DataReader 変換先を追加し、集計変換の出力を DataReader 変換先に接続します。 サンプル コードでは、DataReader の名前として "DataReaderDest" が使用されています。 変換先に対して使用可能な単一の入力列 CustomerCount を選択します。
パッケージを保存します。 次に作成されたテスト アプリケーションではパッケージが実行され、その出力がメモリから直接取得されます。
テスト アプリケーションを作成するには
新しい Windows フォーム アプリケーションを作成します。
%ProgramFiles%\Microsoft SQL Server\100\DTS\Binn 内の同じ名前のアセンブリを参照して、
Microsoft.SqlServer.Dts.DtsClient
名前空間への参照を追加します。次のサンプル コードをコピーし、フォームのコード モジュールに貼り付けます。
dtexecArgs
変数の値を必要に応じて変更し、パッケージを実行するためにdtexec.exeに必要なコマンド ライン パラメーターが含まれるようにします。 サンプル コードは、ファイル システムからパッケージを読み込みます。dataReaderName
変数の値を必要に応じて変更し、パッケージ内の DataReader 変換先の名前が含まれるようにします。ボタンとテキスト ボックスをフォームに追加します。 サンプル コードでは、ボタンの名前として
btnRun
を使用し、テキスト ボックスの名前としてtxtResults
します。アプリケーションを実行し、ボタンをクリックします。 パッケージの実行中に一時停止したら、パッケージによって計算された集計値 (Canada の顧客数) が、フォーム上のテキスト ボックスに表示されます。
サンプル コード
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 を最新の状態に保つ
Microsoft からの最新のダウンロード、記事、サンプル、ビデオ、およびコミュニティから選択したソリューションについては、MSDN の Integration Services ページを参照してください。
MSDN の Integration Services のページを参照する
これらの更新が自動で通知されるようにするには、ページの RSS フィードを定期受信します。
参照
ローカル実行とリモート実行の違いについてプログラムによるローカル パッケージの読み込みと実行リモート パッケージのプログラムによる読み込みと実行