SqlPipe オブジェクト
以前のバージョンの SQL Server では、結果や出力パラメーターを呼び出し側のクライアントに送信するストアド プロシージャ (または拡張ストアド プロシージャ) を作成することがごく一般的でした。
Transact-SQL ストアド プロシージャでは、0 行以上の行を返す SELECT ステートメントはすべて、接続している呼び出し側の "パイプ" に結果を送信します。
SQL Server で実行されている CLR (共通言語ランタイム) データベース オブジェクトの場合は、SqlPipe オブジェクトの Send メソッドを使用して、接続しているパイプに結果を送信できます。SqlPipe オブジェクトを取得するには、SqlContext オブジェクトの Pipe プロパティにアクセスします。SqlPipe クラスは、概念的には ASP.NET の Response クラスに似ています。詳細については、.NET Framework Software Development Kit の SqlPipe クラスのリファレンス ドキュメントを参照してください。
表形式の結果とメッセージを返す
SqlPipe には、3 つのオーバーロードを持つ Send メソッドがあります。この 3 つのオーバーロード メソッドを次に示します。
void Send(string message)
void Send(SqlDataReader reader)
void Send(SqlDataRecord record)
Send メソッドでは、データがそのままクライアントまたは呼び出し元に送信されます。通常、SqlPipe の出力を使用するのはクライアントですが、入れ子になった CLR ストアド プロシージャの場合、ストアド プロシージャが出力のコンシューマーになる可能性もあります。たとえば、Procedure1 がコマンド テキスト "EXEC Procedure2" の SqlCommand.ExecuteReader() を呼び出すとします。Procedure2 もマネージ ストアド プロシージャです。ここで Procedure2 が SqlPipe.Send( SqlDataRecord ) を呼び出すと、行はクライアントではなく、Procedure1 のリーダーに送信されます。
Send メソッドは、クライアントで情報メッセージとして表示される文字列メッセージを送信します。これは、Transact-SQL の PRINT と同等です。また、SqlDataRecord を使用して単一行の結果セットを送信することも、SqlDataReader を使用して複数行の結果セットを送信することもできます。
SqlPipe オブジェクトには、ExecuteAndSend メソッドもあります。このメソッドは、(SqlCommand オブジェクトで渡された) コマンドを実行し、その結果を直接呼び出し側に返送するために使用できます。送信されたコマンドにエラーがある場合、パイプに例外が送信されますが、呼び出し元のマネージ コードにもコピーが送信されます。呼び出し元コードが例外をキャッチしない場合は、履歴を伝わり Transact-SQL コードに反映され、2 度出力に表示されます。呼び出し元コードが例外をキャッチした場合、パイプ コンシューマーにはまだエラーが表示されますが、重複するエラーはありません。
このメソッドは、コンテキスト接続に関連付けられた SqlCommand だけを受け取ります。コンテキスト接続以外に関連付けられたコマンドを受け取ることはできません。
カスタム結果セットを返す
マネージ ストアド プロシージャでは、SqlDataReader 以外からの結果セットを送信できます。SendResultsStart メソッドでは、SendResultsRow や SendResultsEnd と同様に、ストアド プロシージャからクライアントにカスタム結果セットを送信できます。
SendResultsStart は、SqlDataRecord を入力として受け取ります。さらに、結果セットの先頭にマークを付け、レコード メタデータを使用して、結果セットを説明するメタデータを生成します。SendResultsStart を使ってレコードの値が送信されることはありません。以降、SendResultsRow を使用して送信されるすべての行は、そのメタデータ定義に一致する必要があります。
注 |
---|
SendResultsStart メソッドを呼び出した後に呼び出せるのは、SendResultsRow と SendResultsEnd のみです。SqlPipe の同じインスタンスで他のどのメソッドを呼び出しても、InvalidOperationException が発生することになります。SendResultsEnd は、SqlPipe を初期状態に戻し、他のメソッドを呼び出せるようにします。 |
例
uspGetProductLine ストアド プロシージャは、指定した製品ライン内のすべての製品の名前、製品番号、色、および表示価格を返します。このストアド プロシージャは、prodLine の完全一致を受け入れます。
C#
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void uspGetProductLine(SqlString prodLine)
{
// Connect through the context connection.
using (SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
SqlCommand command = new SqlCommand(
"SELECT Name, ProductNumber, Color, ListPrice " +
"FROM Production.Product " +
"WHERE ProductLine = @prodLine;", connection);
command.Parameters.AddWithValue("@prodLine", prodLine);
try
{
// Execute the command and send the results to the caller.
SqlContext.Pipe.ExecuteAndSend(command);
}
catch (System.Data.SqlClient.SqlException ex)
{
// An error occurred executing the SQL command.
}
}
}
};
Visual Basic
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Partial Public Class StoredProcedures
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub uspGetProductLine(ByVal prodLine As SqlString)
Dim command As SqlCommand
' Connect through the context connection.
Using connection As New SqlConnection("context connection=true")
connection.Open()
command = New SqlCommand( _
"SELECT Name, ProductNumber, Color, ListPrice " & _
"FROM Production.Product " & _
"WHERE ProductLine = @prodLine;", connection)
command.Parameters.AddWithValue("@prodLine", prodLine)
Try
' Execute the command and send the results
' directly to the caller.
SqlContext.Pipe.ExecuteAndSend(command)
Catch ex As System.Data.SqlClient.SqlException
' An error occurred executing the SQL command.
End Try
End Using
End Sub
End Class
次の Transact-SQL ステートメントは、ツーリング自転車製品の一覧を返す uspGetProduct プロシージャを実行します。
EXEC uspGetProductLineVB 'T'