web-dev-qa-db-ja.com

カーソルからテーブル変数にフェッチする方法は?

次のように定義されたカーソルがあります。

DECLARE idCursor CURSOR         
    FOR SELECT DISTINCT [id], [data]
        FROM #tempTable  

そして、私は次のように定義された変数を持っています:

DECLARE @currentId TABLE (
                            [id] int,
                            [data] char(1)
                         );  

しかし、次の結果を@currentIdにフェッチしようとすると

FETCH NEXT FROM idCursor INTO @currentId  

私はこのエラーを受け取ります:

Must declare the scalar variable "@currentId".  

テーブルでカーソルフェッチの結果を取得するにはどうすればよいですか? 2つの変数を宣言して結果を個別に保存できることを理解しています。しかし、時間のかかる多くの列を持つテーブルの場合。

3
hazrmard

いいえ、スカラー値をカーソル行からテーブル変数にフェッチすることはできません。変数を宣言してフェッチし、次に挿入する必要があります。

FETCH NEXT FROM idCursor INTO @id, @data;
INSERT @currentId([id],[data]) SELECT @id, @data;

ただし、カーソルがまったく必要ない場合もあるでしょう。なぜ一度に1行ずつ処理するのですか?なぜ@table元々入力されていたクエリを含む変数#tempRemaining

INSERT @currentId([id], [data])
SELECT DISTINCT [id], [data]
    FROM #tempTable;

または単に#tempTable単独で、テーブル変数を完全にスキップしますか?たぶん#tempテーブルをスキップしていますか?テーブル変数と組み合わせたカーソルand #tempテーブルは悪夢のように聞こえます。

Celkoのように聞こえるリスクがありますが、これは1970年代のフラットファイル処理に非常によく似ています。さらに、これらの変数を宣言できないほど多くの列があることはさらに悪いことです。

6
Aaron Bertrand

カーソルを使用した簡単な例:

DECLARE @CustomerID as INT;
declare @msg varchar(max)
DECLARE @BusinessCursor as CURSOR;

SET @BusinessCursor = CURSOR FOR
SELECT CustomerID FROM Customer WHERE CustomerID IN ('3908745','3911122','3911128','3911421')

OPEN @BusinessCursor;
    FETCH NEXT FROM @BusinessCursor INTO @CustomerID;
    WHILE @@FETCH_STATUS = 0
        BEGIN
            SET @msg = '{
              "CustomerID": "'+CONVERT(varchar(10), @CustomerID)+'",
              "Customer": {
                "LastName": "LastName-'+CONVERT(varchar(10), @CustomerID) +'",
                "FirstName": "FirstName-'+CONVERT(varchar(10), @CustomerID)+'",    
              }
            }|'
        print @msg
    FETCH NEXT FROM @BusinessCursor INTO @CustomerID;
END
0
Agnel Amodia