web-dev-qa-db-ja.com

SQL Serverでのカーソルの使用とは何ですか?

データベースカーソルを使用したい。最初に、その使用法と構文を理解する必要があり、どのシナリオでこれをストアドプロシージャで使用できますか? SQL Serverのバージョンごとに異なる構文はありますか?

いつ使用する必要がありますか?

26
Red Swan

カーソルは、結果セットを取得するのではなく、結果セットの行を明示的に列挙するメカニズムです。

ただし、書くことに慣れているプログラマーには使いやすいかもしれませんが、While Not RS.EOF Do ...、それらは通常、SQL Serverストアドプロシージャ内で可能な限り回避するべきものです。カーソルを使用せずにクエリを作成できる場合、オプティマイザはそれを実装するための高速な方法を見つけることができます。 。

正直なところ、カタログ内のすべてのインデックスをループして再構築するなどのいくつかの管理タスクを除いて、避けられないカーソルの現実的なユースケースを見つけたことがありません。レポートの生成や差し込み印刷で何らかの用途があるかもしれませんが、データベースと通信するアプリケーションでカーソルのような作業を行う方がおそらく効率的です。

38
Jeffrey Hantin

カーソルが使用されるのは、サブクエリでレコードを行ごとにフェッチできるため、カーソルを使用してレコードをフェッチするためです

カーソルの例:

DECLARE @eName varchar(50), @job varchar(50)

DECLARE MynewCursor CURSOR -- Declare cursor name

FOR
Select eName, job FROM emp where deptno =10

OPEN MynewCursor -- open the cursor

FETCH NEXT FROM MynewCursor
INTO @eName, @job

PRINT @eName + ' ' + @job -- print the name

WHILE @@FETCH_STATUS = 0

BEGIN

FETCH NEXT FROM MynewCursor 
INTO @ename, @job

PRINT @eName +' ' + @job -- print the name

END

CLOSE MynewCursor

DEALLOCATE MynewCursor

出力:

ROHIT                           PRG  
jayesh                          PRG
Rocky                           prg
Rocky                           prg
16
rohit vyas

カーソルは、行ごとにデータ行を取得するために使用される場合があります。ループステートメント(whileまたはforループ)のように動作します。 SQLプロシージャーでカーソルを使用するには、次のことを行う必要があります。1.結果セットを定義するカーソルを宣言します。 2.カーソルを開いて、結果セットを確立します。 3.必要に応じて、一度に1行ずつ、カーソルからデータをローカル変数にフェッチします。 4.完了したらカーソルを閉じます。

例:

declare @tab table
(
Game varchar(15),
Rollno varchar(15)
)
insert into @tab values('Cricket','R11')
insert into @tab values('VollyBall','R12')

declare @game  varchar(20)
declare @Rollno varchar(20)

declare cur2 cursor for select game,rollno from @tab 

open cur2

fetch next from cur2 into @game,@rollno

WHILE   @@FETCH_STATUS = 0   
begin

print @game

print @rollno

FETCH NEXT FROM cur2 into @game,@rollno

end

close cur2

deallocate cur2
8
Murugan

カーソル自体は反復子です(WHILEなど)。イテレータとは、レコードセット(別名、選択されたデータ行のセット)を走査し、走査中に操作を行う方法を意味します。操作は、たとえばINSERTまたはDELETEです。したがって、たとえばデータ取得に使用できます。カーソルは、結果セットの行を順番に処理します(行ごと)。カーソルは、行セット内の1行へのポインターとして表示でき、一度に1行のみを参照できますが、必要に応じて結果セットの他の行に移動できます。

この link には、構文の明確な説明があり、追加情報と例が含まれています。

カーソルはSprocsでも使用できます。これらは、複数のクエリの代わりに1つのクエリを使用してタスクを実行できるようにするショートカットです。ただし、カーソルはスコープを認識し、sprocのスコープ外では未定義と見なされ、それらの操作は単一のプロシージャ内で実行されます。ストアドプロシージャは、プロシージャで宣言されていないカーソルを開いたり、フェッチしたり、閉じたりすることはできません。

1
igelr

リターンセットの異なる行にある特性の比較を行う場合、または特定の場合に標準の出力行形式とは異なる出力行形式を作成する場合は、カーソルを使用することをお勧めします。 2つの例が思い浮かびます。

  1. 1つは大学で、クラスの追加と削除ごとにテーブルに独自の行がありました。設計が悪かったかもしれませんが、行全体を比較して、その人がクラスにいたかどうかを判断するために、追加および削除した行の数を知る必要がありました。 SQLだけでそれを行う簡単な方法は考えられません。

  2. もう1つの例は、GLジャーナル。ジャーナルの借方と貸方の任意の数を取得し、行セットのリターンに多数のジャーナルがあり、ジャーナルを書きたい総勘定元帳に仕訳するために仕訳を完了するたびに合計行。カーソルを使用すると、ある仕訳を離れて別の仕訳を開始し、借方と貸方のアキュムレータを持ち、仕訳の合計行(またはテーブル挿入)を書くことができますデビット/クレジットラインとは異なります。

1
flashgordon

SQLサーバーでは、必要なときにカーソルが使用されます。結果セットのすべての行を一度に1つずつ操作するT-SQLコマンドの代わりに、シングルトンでデータベーステーブルのレコードを更新する必要があるときにカーソルを使用します。つまり、行ごとに1行ずつフェッチするか、行ごとにフェッチします。

カーソルの操作は、いくつかの手順で構成されています。

宣言-宣言は、新しいカーソルを定義するために使用されます。オープン-カーソルによって定義されたSQLステートメントを実行することにより、カーソルが開かれ、データが設定されます。フェッチ-カーソルを開くと、カーソルから行を1つずつ取得できます。閉じる-データ操作の後、カーソルを明示的に閉じる必要があります。割り当て解除-最後に、カーソル定義を削除し、カーソルに関連付けられているすべてのシステムリソースを解放する必要があります。構文

DECLARE cursor_name CURSOR [LOCAL |グローバル] [FORWARD_ONLY |スクロール] [静的|キーセット|ダイナミック| FAST_FORWARD] [読み取り専用| SCROLL_LOCKS | OPTIMISTIC] [TYPE_WARNING] select_statementの場合[UPDATE [OF column_name [、... n]]] [;]の場合