テーブル変数を選択するストアド プロシージャ内で奇妙なことがわかりました。カーソルの最初の反復でフェッチされた値を (後続の反復で) 常に返します。これを証明するサンプルコードを次に示します。
DECLARE @id AS INT;
DECLARE @outid AS INT;
DECLARE sub_cursor CURSOR FAST_FORWARD
FOR SELECT [TestColumn]
FROM testtable1;
OPEN sub_cursor;
FETCH NEXT FROM sub_cursor INTO @id;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @Log TABLE (LogId BIGINT NOT NULL);
PRINT 'id: ' + CONVERT (VARCHAR (10), @id);
INSERT INTO Testtable2 (TestColumn)
OUTPUT inserted.[TestColumn] INTO @Log
VALUES (@id);
IF @@ERROR = 0
BEGIN
SELECT TOP 1 @outid = LogId
FROM @Log;
PRINT 'Outid: ' + CONVERT (VARCHAR (10), @outid);
INSERT INTO [dbo].[TestTable3] ([TestColumn])
VALUES (@outid);
END
FETCH NEXT FROM sub_cursor INTO @id;
END
CLOSE sub_cursor;
DEALLOCATE sub_cursor;
ただし、SOにコードを投稿してさまざまな組み合わせを試しているときに、下の行からトップを削除すると、カーソル内のテーブル変数から正しい値が得られることがわかりました。
SELECT TOP 1 @outid = LogId FROM @Log;
これはこのようになります
SELECT @outid = LogId FROM @Log;
ここで何が起こっているのかわかりません。ループの繰り返しごとに新しいテーブルが作成されると考えて、テーブル変数の TOP 1 が機能するはずだと思いました。誰かがテーブル変数のスコープと有効期間に光を当てることができますか?
更新:ここで奇妙な動作を回避する解決策があります。解決策として、ループの前にテーブルを宣言し、ループの先頭ですべての行を削除しました。