T-SQLで大量のデータをループする場合、インターネットで目にするほとんどの例では、次のようなパターンを使用しています。
declare @someVariable int
declare @remainingRows int
select someColumn from someTables into #someTempTable
select @remainingRows = count(*) from #someTempTable
while @remainingRows > 0 begin
select top 1 @someVariable = someColumn from #someTempTable
-- Do stuff
delete top 1 from #someTempTable
select @remainingRows = count(*) from #someTempTable
end
これは、次のようなカーソルを使用するサンプルよりもはるかに一般的なようです。
declare @someVariable int
select someColumn from someTables into #someTempTable
declare @someCursor cursor for select someColumn from #someTempTable
open @someCursor
fetch next @someVariable from @someCursor
while @@fetch_status = 0 begin
-- Do stuff
fetch next @someVariable from @someCursor
end
close @someCursor
パフォーマンスの理由について言及することもありますが、私には直観に反しています。一連のデータを繰り返し処理する前方専用の読み取り専用カーソルは、一時テーブルを常にクエリして更新するよりもはるかに効率的ではないでしょうか。間違ったオプションを使用してテーブルを反復するカーソルであった場合、更新のためにテーブルがロックされる可能性がありますが、非共有の一時テーブル上のカーソルには問題がないと思いますか?
ボーナス質問;カーソルに問題がなければ、スナップショット分離を使用する通常のクエリにカーソルを合わせても安全です。一時テーブルを手動で作成する煩わしさを回避できます。
DECLARE @someCursor CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR
SELECT something
FROM tables
いいえ、ループの方がカーソルよりも速いとは限りませんが、ループの方が快適な場合もあります。自分で一度にループ書き込みフェーズを経験しました。また、カーソルにはいくつかの種類があるため、正しいタイプのカーソルを選択することは重要な詳細です。
Aaron Bertrand(2012年から)は、次の場所でいくつかの比較テストを実施したため、おそらくあなたの質問に回答しています。
つまり、適切なカーソルがいくつかのループ構造よりも大幅に高速に実行されることがわかりました。
彼の比較を読むと、カーソルに慣れるのに役立ちます。
しかし、それらが必要なときだけ。