返された結果セットがすべて同じ構造である場合は、それらを一時テーブルにダンプできます。ただし、フィールドのデータを使用して特定の行がどの結果セットから来たかを判断できない場合、すべての結果セットが得られ、そうでないものを除外する方法がないため、これだけでは不十分です。欲しいです。
複数の結果セットを個別に操作する唯一の方法は、構造が同じか異なるかに関係なく、アプリ コード (つまり、クライアント接続) を使用することです。別のクエリのコンテキスト内でこれを行う場合は、SQLCLR を使用する必要があります。
以下の C# コードは、4 つの結果セットを返す T-SQL ストアド プロシージャを実行する SQLCLR ストアド プロシージャを示しています。最初の 2 つの結果セットをスキップし、3 番目の結果セットのみを返します。これにより、必要に応じて SQLCLR ストアド プロシージャを INSERT...EXEC で使用できます。
次のコードによって呼び出される T-SQL ストアド プロシージャのコードは、C# コード ブロックの下に示されています。T-SQL テスト プロシージャが実行sp_who2
され、そのプロシージャによって返されるフィールドのサブセットのみが返されます。これは、読み取っているものとまったく同じ結果セットを返す必要がないことを示しています。輸送中に操作できます。
C# SQLCLR プロシージャ:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public class TheProc
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void Get3rdResultSetFromGetStuckWorkflowInstances()
{
int _ResultSetsToSkip = 2; // we want the 3rd result set
SqlConnection _Connection = null;
SqlCommand _Command = null;
SqlDataReader _Reader = null;
try
{
_Connection = new SqlConnection("Context Connection = true;");
_Command = _Connection.CreateCommand();
_Command.CommandType = CommandType.StoredProcedure;
_Command.CommandText = "tempdb.dbo.MultiResultSetTest";
// (optional) add parameters (but don't use AddWithValue!)
// The SqlDataRecord will be used to define the result set structure
// and act as a container for each row to be returned
SqlDataRecord _ResultSet = new SqlDataRecord(
new SqlMetaData[]
{
new SqlMetaData("SPID", SqlDbType.Char, 5),
new SqlMetaData("Status", SqlDbType.NVarChar, 30),
new SqlMetaData("Login", SqlDbType.NVarChar, 128),
new SqlMetaData("HostName", SqlDbType.NVarChar, 128),
new SqlMetaData("BlkBy", SqlDbType.VarChar, 5),
new SqlMetaData("DBName", SqlDbType.NVarChar, 128)
});
SqlContext.Pipe.SendResultsStart(_ResultSet); // initialize result set
_Connection.Open();
_Reader = _Command.ExecuteReader();
// Skip a predefined number of result sets
for (int _Index = 0;
_Index < _ResultSetsToSkip && _Reader.NextResult();
_Index++) ;
// Container used to move 1 full row from the result set being read
// to the one being sent, sized to the number of fields being read
Object[] _TempRow = new Object[_Reader.FieldCount];
while (_Reader.Read())
{
_Reader.GetValues(_TempRow); // read all columns
_ResultSet.SetValues(_TempRow); // set all columns
SqlContext.Pipe.SendResultsRow(_ResultSet); // send row
}
}
catch
{
throw;
}
finally
{
if(SqlContext.Pipe.IsSendingResults)
{
SqlContext.Pipe.SendResultsEnd(); // close out result set being sent
}
if(_Reader != null && !_Reader.IsClosed)
{
_Reader.Dispose();
}
_Command.Dispose();
if (_Connection != null && _Connection.State != ConnectionState.Closed)
{
_Connection.Dispose();
}
}
return;
}
}
T-SQL テスト プロシージャ:
USE [tempdb]
SET ANSI_NULLS ON;
IF (OBJECT_ID('dbo.MultiResultSetTest') IS NOT NULL)
BEGIN
DROP PROCEDURE dbo.MultiResultSetTest;
END;
GO
CREATE PROCEDURE dbo.MultiResultSetTest
AS
SET NOCOUNT ON;
SELECT 1 AS [ResultSet], 'asa' AS [test];
SELECT 2 AS [ResultSet], NEWID() AS [SomeGUID], GETDATE() AS [RightNow];
EXEC sp_who2;
SELECT 4 AS [ResultSet], CONVERT(MONEY, 131.12) AS [CashYo];
GO
EXEC tempdb.dbo.MultiResultSetTest;
すること:
_ResultSetsToSkip
適宜調整してください。最初の結果セットのみが必要な場合は、単純に両方_ResultSetsToSkip
とfor
ループを削除します。
_ResultSet
適宜定義
_Command.CommandText
「spDebuggerViews_GetStuckWorkflowInstances」に設定
SqlParameter
(つまり@workflowSpaceId='00000000-0000-0000-0000-000000000000',@pageNum=1,@pageSize=100000,@orderByColumn=N'fldid',@sortOrder=1,@workflowInstanceId=0,@stuckInstanceType=1,@createdDateFrom='1900-01-01 00:00:00',@createdDateTo='9999-01-01 23:59:59',@updatedDateFrom='1900-01-01 00:00:00',@updatedDateTo='9999-01-01 23:59:59'
)を介して必要なパラメータを作成します
必要に応じて、SQLCLR プロシージャに入力パラメーターを追加して、特定SqlParameter
の s の値を設定するために使用できるようにします。
次に、次のように使用します。
INSERT INTO #stalledp
(RowNumber,fldid,fldLastUpdated,fldCreationDate,fldName,fldPending)
EXEC Get3rdResultSetFromGetStuckWorkflowInstances;