2

SQL Server 2008 R2 でデータベース テーブルの行をループする最良の方法は何ですか?

foreach ( ) の記述にかなり似ていて、非常にパフォーマンスの高いものを探しています。

ありがとう

4

3 に答える 3

4

最高のパフォーマンス: テーブルの行をループしない。セットベースの操作を使用します。

ここに理由の良い議論があります

于 2010-10-11T22:37:48.617 に答える
2

おそらく、カーソルが必要ですか?SQL Server Cursor Examplesを参照してください(リンクも提供し、問題/代替手段/理由について説明しています)。「最良」の定義を満たす場合もあれば、満たさない場合もあります。SQL DQL は、実際に「セット操作」を使用するのが好きです (これは、そのように設計されており、curor の使用にはいくつかの注意事項があります)。

ハッピーコーディング。

編集 (marc_s の場合):カーソル が必要になる場合があります (特に、SQL を動的に生成する場合は -- わかりませんが)。この操作の理由は特定されていないため、上記の回答は中立的なものになるように努めています (ただし、リンク内の文言と情報は、一般的なカーソルの使用に影を落としています)。カーソルにはいくつかの問題がありますが (実際には他の DQL コンストラクトには適合しません)、特定の操作を実行するための最良の (または唯一の) 方法である可能性があります。

于 2010-10-11T22:38:27.943 に答える
0

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
于 2014-06-09T18:02:10.343 に答える