目次へ

12.2. カーソル

前節でも述べましたが、SQL はデータベースから複数行のデータを取り出し、一括して処理することに向いています。しかし、他のプログラムや SQL 非標準のストアドプロシージャにおけるループでは、一行ごとにデータを処理したい場合があります。このような場合にカーソルを利用します。カーソルとは、クエリの結果集合を一時的に蓄えておくための仮想的な作業領域のことです。この中の現在位置を示すポインタと呼ばれるものが、ループ処理が実行されるたびに一行ずつ進んでいき、次の処理対象を示します。カーソルは非手続き型の SQL で、C や JAVA などの手続き型言語と同様の処理形態を可能とする手法と言えます。

カーソルを利用することにより、よりきめ細かな処理が可能になります。

カーソル

カーソルを使用するときの手順は次のようになっています。

  1. カーソルの宣言
  2. カーソルを開く
  3. 一行ごとにデータを取り出す(ループ処理)
  4. カーソルを閉じる

まず、カーソルを宣言するときの SQL について説明します。DECLARE CURSOR 文を用いて宣言します。宣言とは定義することと理解して問題ありません。

  DECLARE カーソル名 [ INSENSITIVE ] [ SCROLL ] CURSOR
     FOR { SELECT文 [ 更新可能性句 ] } | {準備された文} ;  

INSENSITIVE を指定するとカーソルを開いた後、カーソルの内容が固定されます。カーソルを開いている間、他のトランザクションによるデータの変更の影響は受けません。INSENSITIVE と指定できるのは、後で説明する読み取り専用カーソルに限定されます。

SCROLL を指定すると、後に述べる FETCH 文の「方向」で NEXT 以外も指定することができるようになります。SCROLL を指定しない場合は、NEXT だけがサポートされます。これも、読み取り専用カーソルに限定されます。

更新可能性句は、そのカーソルが更新可能なのか、読み取り専用なのかを指定するものです。更新可能性句は次のように記述します。初期値は READ ONLY になっていますので、読み取り専用である場合は、明示的に指定する必要はありません。

  FOR { READ ONLY | UPDATE [ OF 列リスト] }  

UPDATE を指定すると、更新可能なカーソルと定義されます。UPDATE の後ろに記述された特定の列に対してカーソルを更新することができるようになります。

「準備された文」のところには、あらかじめ PREPARE 文により SQL 文と文字列を関連付けておき、その文字列を記述します。その文字列を記述することにより、動的に SQL 文が呼び出されます。PREPARE 文の基本構文は次の通りです。

 PREPARE [ GLOBAL | LOCAL ] SQL文名 FROM 文字列変数 ;

PREPARE 文では、予め文字列変数 := ' SQL 文 '; としておき、DECLARE 文で SQL 文名が呼び出されたときに、文字列変数に格納された SQL 文が出力されます。また GLOBAL を指定すると、DECLARE 文などの SQL 文から呼び出すことが可能であることを示し、LOCAL を指定すると、モジュールまたはコンパイルユニットからしか呼び出すことができないことを示します。

次に、カーソルを開く方法ですが、これは OPEN CURSOR 文を使用します。基本構文は次の通りです。

  OPEN カーソル名 [ USING 値ソース ] ; 

DECLARE 文で定義されたカーソルを開きます。カーソルを開くことにより、カーソルのデータを処理することができるようになります。USING 句は、動的 SQL の場合にのみ指定します。値ソースは次のように記述して指定します。

   パラメータ | { SQL DESCRIPTOR 記述子 }  

このように二通りの指定方法がありますが、パラメータはアプリケーションから渡される変数リストを指定するものです。後者の SQL DESCRIPTOR は、動的に生成される SQL 文のパラメータを取り出すときに使用されるものです。

次に FETCH 文を使用してカーソルから一行ずつデータを取り出す方法を説明します。OPEN 文で利用できるようになったカーソルから、データを一行ずつ取り出してアプリケーションによるループ処理を行います。FETCH 文の基本構文は次の通りです。

  FETCH [ [ 方向 ] FROM ] カーソル名 INTO 変数リスト ; 

「方向」は行を示すポインタがどこに移動した後に、行のデータを読み取るのかを指定するものです。「方向」の指定の仕方は、次の通りです。

 NEXT | PRIOR | FIRST | LAST |
 { ABSOLUTE | RELATIVE オフセット }

NEXT を指定すると、ポインタは次の行へ移動します。最終行の次の行にポインタがあるときは、「NO DATA」という情報がポインタから返されます。この情報を、アプリケーションやストアドプロシージャが受け取ることができ、ループ処理を終了したりします。PRIOR を指定すると、ポインタは前の行へ移動します。先頭行の前の行にポインタがあるときは、「NO DATA」を返します。FIRST はポインタを先頭行へ、LAST はポインタを最終行へ移動します。

ABSOLUTE オフセットを指定すると、オフセットの指定する行へポインタは移動します。オフセット = 5 の場合は、5 番目の行に移動します。オフセットの示す行が、カーソルの最大行を超える場合は「NO DATA」を返します。RELATIVE オフセットを指定すると、オフセットに指定した行だけ移動します。例えば、オフセット = 3 の場合、現在行が 10 番目の行であるならば、13 番目の行へ移動します。また、オフセット = -3 の場合は、7 番目の行へ移動します。ポインタの行き先が先頭行より前、または最終行より後ろになる場合は、「NO DATA」を返します。ちなみに、「方向」を省略すると NEXT が採用されます。

ターゲット変数リストは、ポインタの示す行のデータを格納する変数のことで、アプリケーションやストアドプロシージャで使用する変数です。

つまり、FETCH 文が実行されると、現在の行からポインタを「方向」で示した行へ移動し、その行の各データを変数リストへ格納するのです。FROM は省略しても問題ありません。

最後に、処理が終わったカーソルは閉じなければなりません。カーソルを閉じるための基本構文は次の通りです。

 CLOSE カーソル名 ;   

カーソルを閉じることにより、カーソルに蓄えられていたクエリの結果集合が破棄されます。

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp