SQL Server 2008 R2 でデータベース テーブルの行をループする最良の方法は何ですか?
foreach ( ) の記述にかなり似ていて、非常にパフォーマンスの高いものを探しています。
ありがとう
SQL Server 2008 R2 でデータベース テーブルの行をループする最良の方法は何ですか?
foreach ( ) の記述にかなり似ていて、非常にパフォーマンスの高いものを探しています。
ありがとう
最高のパフォーマンス: テーブルの行をループしない。セットベースの操作を使用します。
おそらく、カーソルが必要ですか?SQL Server Cursor Examplesを参照してください(リンクも提供し、問題/代替手段/理由について説明しています)。「最良」の定義を満たす場合もあれば、満たさない場合もあります。SQL DQL は、実際に「セット操作」を使用するのが好きです (これは、そのように設計されており、curor の使用にはいくつかの注意事項があります)。
ハッピーコーディング。
編集 (marc_s の場合):カーソル が必要になる場合があります (特に、SQL を動的に生成する場合は -- わかりませんが)。この操作の理由は特定されていないため、上記の回答は中立的なものになるように努めています (ただし、リンク内の文言と情報は、一般的なカーソルの使用に影を落としています)。カーソルにはいくつかの問題がありますが (実際には他の DQL コンストラクトには適合しません)、特定の操作を実行するための最良の (または唯一の) 方法である可能性があります。
T-SQL でレコードをループすることは、運用コードでは推奨されませんが、必要になる場合があります。Microsoft のサポート サイト (いずれもカーソルを使用していません) には、いくつかの優れた例があります: http://support.microsoft.com/kb/111401
そして、ここにメソッドのリストがあります:
1 つの方法は、一時テーブルを使用することです。この方法では、最初の SELECT ステートメントの "スナップショット" を作成し、それを "カーソル" のベースとして使用します。例えば:
/********** example 1 **********/
declare @au_id char( 11 )
set rowcount 0
select * into #mytemp from authors
set rowcount 1
select @au_id = au_id from #mytemp
while @@rowcount <> 0
begin
set rowcount 0
select * from #mytemp where au_id = @au_id
delete #mytemp where au_id = @au_id
set rowcount 1
select @au_id = au_id from #mytemp<BR/>
end
set rowcount 0
2 番目の方法は、min 関数を使用してテーブルを一度に 1 行ずつ「移動」することです。このメソッドは、クエリで処理されている現在の行よりも大きな一意の識別子が新しい行にある場合に、ストアド プロシージャの実行開始後に追加された新しい行をキャッチします。例えば:
/********** example 2 **********/
declare @au_id char( 11 )
select @au_id = min( au_id ) from authors
while @au_id is not null
begin
select * from authors where au_id = @au_id
select @au_id = min( au_id ) from authors where au_id > @au_id
end
注: 例 1 と 2 はどちらも、ソース テーブルの各行に一意の識別子が存在することを前提としています。場合によっては、一意の識別子が存在しないことがあります。その場合は、一時テーブル メソッドを変更して、新しく作成したキー列を使用できます。例えば:
/********** example 3 **********/
set rowcount 0
select NULL mykey, * into #mytemp from authors
set rowcount 1
update #mytemp set mykey = 1
while @@rowcount > 0
begin
set rowcount 0
select * from #mytemp where mykey = 1
delete #mytemp where mykey = 1
set rowcount 1
update #mytemp set mykey = 1
end
set rowcount 0