【SQL Server】カーソル CURSOR

今回はカーソルについてです。
基本的にデータベースのデータ操作を行う際はメモリIO、ディスクIOを抑えるため一括して行う方が効率良くデータ処理ができます。しかしながら、一括でデータ操作ができないケースも出てきます。
そんな時に活躍するのがカーソル(CURSOR)です。

カーソル CURSORとは

詳細な説明はSQL Serverのドキュメントで見て欲しいのですが、カーソル(CURSOR)はselectで抽出したデータに対して一行づつ取り出すことができる逐次処理ができる仕組み・機能です。
一行づつ取り出しができるので、その行に対して処理を書けることができます。一括で処置ができない、または一括では処理が重たくてレスポンスが悪くなるなどのケースに使用します。
カーソル CURSORの使い方

カーソル(CURSOR)の使い方は難しくありません。カーソル(CURSOR)のネストもできます。ただし、もともと複雑なことを対象に処理を行うことを考えるとトランザクション設計などはきちんとしないといけませんが。。。

カーソル(CURSOR)を使うには、カーソルの宣言を行います。カーソルの宣言にはデータを抽出するSQLも合わせて示すことになります。
また、抽出した際に抽出データを入れる変数も予め宣言しておかなくてはいけません。
その後、カーソル(CURSOR)をOPENして、データが無くなる(Fetchが失敗する)までループさせ一行づつ処理を行います。
データが無くなる(強制的にループを終了させる)った後は、カーソル(CURSOR)をCLOSEして、カーソル(CURSOR)をDEALLOCATEして終わりです。

DEALLOCATEを使ったSQL例

行っていることは、

  • 変数テーブルを作成
  • 適当にデータを入れる
  • 比較する為にテーブル内のデータ抽出表示
  • 抽出用の変数を宣言
  • カーソル(CURSOR)を宣言
  • カーソル(CURSOR)のOPEN
  • Fetch(一行取り出す)
  • while文でFetchが失敗してないか評価
  • Fetchできていたら、その行のポイントを前の行のポイントを加算して更新Fetch(一行取り出す)
  • Fetch(一行取り出す)・・・ループ
  • カーソル(CURSOR)をCLOSE
  • カーソル(CURSOR)をDEALLOCATE
  • 比較する為にテーブル内のデータ抽出表示
declare @tbl1 table(
	id int,
	kbn nchar(10) ,
	point int
)

declare @start_id as int
set @start_id=0

while @start_id < 10
	begin
		print @start_id
		insert into @tbl1 values(@start_id, @start_id % 3, @start_id * Rand() * 10)
		set @start_id = @start_id +1
	end

select * from @tbl1

declare @test_id int, @test_point int
declare @add_point int
set @add_point=100

--カーソル
declare test_cursor cursor for
select id, point from @tbl1 where kbn = 1 order by id
open test_cursor

fetch next from test_cursor into @test_id, @test_point

while @@FETCH_STATUS = 0
begin
	update @tbl1 set point+=@add_point where id=@test_id
	set @add_point=@test_point
	fetch next from test_cursor into @test_id, @test_point
end
close test_cursor
deallocate test_cursor

select * from @tbl1

実行結果
sql-result02

以上、カーソル CURSORの使い方まで