37

SQL Server 2005 を使用しています。transact-sql 内からさまざまな結果セットにアクセスする方法を知りたいです。次のストアド プロシージャは 2 つの結果セットを返します。たとえば、別のストアド プロシージャからそれらにアクセスするにはどうすればよいですか?

CREATE PROCEDURE getOrder (@orderId as numeric) AS
BEGIN   
    select order_address, order_number from order_table where order_id = @orderId
    select item, number_of_items, cost from order_line where order_id = @orderId
END

両方の結果セットを個別に反復できる必要があります。

編集:質問を明確にするために、ストアドプロシージャをテストしたいと思います。複数の結果セットを返す VB.NET クライアントから使用される一連のストアド プロシージャがあります。これらはテーブル値関数に変更される予定はありません。実際、手順をまったく変更することはできません。手順を変更することはできません。

プロシージャによって返される結果セットは、同じデータ型または列数ではありません。

4

7 に答える 7

34

簡単に言えば、それはできません。

T-SQL から、ネストされたストアド プロシージャ呼び出しの複数の結果にアクセスする方法はありません。他の人が提案したように、ストアド プロシージャを変更する必要はありません。

完了するには、プロシージャが 1 つの結果を返す場合、次の構文を使用して一時テーブルまたはテーブル変数に挿入できます。

INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...

複数の結果を返すプロシージャに同じ構文を使用できますが、最初の結果のみが処理され、残りは破棄されます。

于 2008-09-12T13:48:13.370 に答える
8

内部データセットを含む SQL2005 CLR ストアド プロシージャを作成することで、これを簡単に行うことができました。

ご覧のとおり、新しい SqlDataAdapter は、デフォルトで、複数の結果セットの sproc を複数のテーブルのデータセットに入力します。これらのテーブルのデータは、書き込みたい呼び出し側 sproc の #Temp テーブルに挿入できます。 dataset.ReadXmlSchemaは、各結果セットのスキーマを表示します。

ステップ 1: 複数結果セット sproc からデータを読み取る sproc の作成を開始する

を。スキーマに従って、結果セットごとに個別のテーブルを作成します。

CREATE PROCEDURE [dbo].[usp_SF_Read] AS
SET NOCOUNT ON;
CREATE TABLE #Table01 (Document_ID VARCHAR(100)
  , Document_status_definition_uid INT
  , Document_status_Code VARCHAR(100) 
  , Attachment_count INT
  , PRIMARY KEY (Document_ID));

b. この時点で、ここで作成する CLR sproc を繰り返し呼び出すために、カーソルを宣言する必要がある場合があります。

ステップ 2: CLR Sproc を作成する

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub usp_SF_ReadSFIntoTables()

    End Sub
End Class

を。を使って接続しNew SqlConnection("context connection=true")ます。

b. コマンド オブジェクト (cmd) を設定して、複数結果セット sproc を含めます。

c. 以下を使用してすべてのデータを取得します。

    Dim dataset As DataSet = New DataSet
    With New SqlDataAdapter(cmd)
        .Fill(dataset) ' get all the data.
    End With
'you can use dataset.ReadXmlSchema at this point...

d. 各テーブルを繰り返し処理し、すべての行を適切な一時テーブル (上記の手順 1 で作成した) に挿入します。

最後の注意: 私の経験では、各レコードがどのバッチから来たのかを知るために、テーブル間にいくつかの関係を強制したい場合があります。

それだけです!

~ ショーン、シアトル近郊

于 2009-05-18T20:02:33.440 に答える
5

あなたにもできるクラッジがあります。オプションのパラメーター N int を sproc に追加します。N のデフォルト値を -1 にします。N の値が -1 の場合、すべての選択を実行します。それ以外の場合は、N 番目の選択を行い、N 番目の選択のみを行います。

例えば、

if (N = -1 or N = 0)
    select ...

if (N = -1 or N = 1)
    select ...

N を指定しない sproc の呼び出し元は、複数のテーブルを含む結果セットを取得します。これらのテーブルの 1 つ以上を別の sproc から抽出する必要がある場合は、N の値を指定して sproc を呼び出すだけです。抽出するテーブルごとに 1 回ずつ sproc を呼び出す必要があります。結果セットから複数のテーブルが必要な場合は非効率的ですが、純粋な TSQL では機能します。

于 2011-08-23T22:21:28.563 に答える
4

INSERT INTO ... EXEC ステートメントには、文書化されていない追加の制限があることに注意してください。ネストすることはできません。つまり、EXEC が呼び出すストアド プロシージャ (またはそれが順番に呼び出すストアド プロシージャ) 自体は、INSERT INTO ... EXEC を実行できません。結果を蓄積するプロセスごとに単一のスクラッチパッドがあるようです。それらがネストされている場合、呼び出し元がこれを開いたときにエラーが発生し、呼び出し先が再度開こうとします。

Matthieu、結果の「タイプ」ごとに個別の一時テーブルを維持する必要があります。また、同じものを複数回実行している場合は、その結果に追加の列を追加して、どの呼び出しから生じたかを示す必要がある場合があります。

于 2008-09-15T21:52:05.883 に答える
2

残念ながら、これを行うことは不可能です。もちろん、問題はそれを許可する SQL 構文がないことです。もちろん、それは「ボンネットの下」で発生しますが、ODBC などを介したアプリケーションからのみ、TSQL でこれらの他の結果を取得することはできません。

ほとんどのものと同様に、それを回避する方法があります。秘訣は、TSQL で ole オートメーションを使用して、各結果セットを順番に開き、指定したテーブルに結果を書き込む ADODB オブジェクトを作成することです (または、結果セットで必要なことを行います)。痛みが好きならDMOでもできます。

于 2008-11-06T19:37:21.500 に答える
1

これを簡単に行うには 2 つの方法があります。結果を一時テーブルに貼り付けてから、sproc から一時テーブルを参照します。もう 1 つの方法は、結果を OUTPUT 変数として使用される XML 変数に入れることです。

ただし、これらのオプションにはどちらにも長所と短所があります。一時テーブルでは、プロシージャを変更する前に、一時テーブルを作成するための呼び出しプロシージャを作成するコードをスクリプトに追加する必要があります。また、手順の最後に一時テーブルをクリーンアップする必要があります。

XML を使用すると、メモリを大量に消費し、処理が遅くなる可能性があります。

于 2008-09-12T13:36:12.667 に答える
0

それらを一時テーブルに選択するか、テーブル値関数を記述して結果セットを返すことができます。結果セットを反復する方法を尋ねていますか?

于 2008-09-12T13:31:51.117 に答える