次の方法で共有


SQL Server で Transact-SQL を使用して結果セットを反復処理する

この記事では、SQL Server で Transact-SQL を使用して結果セットを反復処理するために使用できるさまざまなメソッドについて説明します。

元の製品バージョン: SQL Server
元の KB 番号: 111401

まとめ

この記事では、ストアド プロシージャ、トリガー、または Transact-SQL バッチでカーソルのような FETCH-NEXT ロジックをシミュレートするために使用できるさまざまなメソッドについて説明します。

Transact-SQL ステートメントを使用して結果セットを反復処理する

Transact-SQL ステートメントを使用して結果セットを反復処理するために使用できる 3 つのメソッドを次に示します。 次の例では、 AdventureWorks サンプル データベースの Production.Product テーブルを使用します

1 つの方法は、一時テーブルの使用です。 この方法では、最初の SELECT ステートメントのスナップショットを作成し、カーソルの基礎として使用します。 例えば次が挙げられます。

/********** example 1 **********/
SET NOCOUNT ON
DROP TABLE IF EXISTS #MYTEMP 
DECLARE @ProductID int

SELECT * INTO #MYTEMP FROM Production.Product

SELECT TOP(1) @ProductID = ProductID FROM #MYTEMP

WHILE @@ROWCOUNT <> 0
BEGIN
    SELECT * FROM #MYTEMP WHERE ProductID = @ProductID
    DELETE FROM #MYTEMP WHERE ProductID = @ProductID
    SELECT TOP(1) @ProductID = ProductID FROM #MYTEMP
END

2 つ目の方法は、 min 関数を使用してテーブルを一度に 1 行ずつウォークすることです。 このメソッドは、ストアド プロシージャの実行開始後に追加された新しい行をキャッチします。ただし、新しい行にクエリで処理されている現在の行より大きい一意の識別子がある場合です。 例えば次が挙げられます。

/********** example 2 **********/
SET NOCOUNT ON
DROP TABLE IF EXISTS #MYTEMP 
DECLARE @ProductID int

SELECT @ProductID = min( ProductID ) FROM Production.Product
WHILE @ProductID IS NOT NULL

BEGIN
    SELECT * FROM Production.Product WHERE ProductID = @ProductID
    SELECT @ProductID = min( ProductID ) FROM Production.Product WHERE ProductID > @ProductID
END

Note

例 1 と 2 はどちらも、ソース テーブルの各行に一意の識別子が存在することを前提としています。 場合によっては、一意の識別子が存在しない可能性があります。 その場合は、新しく作成されたキー列を使用するように一時テーブル メソッドを変更できます。 例えば次が挙げられます。

/********** example 3 **********/
SET NOCOUNT ON
DROP TABLE IF EXISTS #MYTEMP 

SELECT NULL AS mykey, * INTO #MYTEMP FROM Production.Product

UPDATE TOP(1) #MYTEMP SET mykey = 1

WHILE @@ROWCOUNT > 0
BEGIN
    SELECT * FROM #MYTEMP WHERE mykey = 1
    DELETE FROM #MYTEMP WHERE mykey = 1
    UPDATE TOP(1) #MYTEMP SET mykey = 1
END

関連情報

ROW_NUMBER (Transact-SQL)