今回はカーソルについてです。
基本的にデータベースのデータ操作を行う際はメモリ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
以上、カーソル CURSORの使い方まで