カーソル(埋め込みSQL)は、応用情報技術者試験のデータベース分野で出題されるテーマです。
CやCOBOLなどの手続き型言語からデータベースを操作する際に必須となる仕組みで、DECLARE・OPEN・FETCH・CLOSEの4操作を正確に区別できるかが問われます。
詳細をクリックして確認
応用情報技術者
★★☆☆☆
ランクC(応用)余裕があれば覚える
用語の定義
情報処理試験を勉強していると、「カーソルって画面のマウスポインタのこと?SQLと何の関係があるの?」と混乱しがちです。
カーソル(Cursor)とは、一言で言うと
「埋め込みSQLにおいて、SELECT文の結果セットを1行ずつホスト言語(親プログラム)に引き渡すための仕組み」
のことです。
イメージとしては、「回転寿司のレーンに置かれた指差し棒」です。
回転寿司では多くの皿がレーン上を流れていますが、一度に全部は取れません。指差し棒で「今この1皿」と指し示して手元に取り、食べ終わったら次の皿を指す。
カーソルはまさにこの「今どの1行を処理しているか」を示すポインタです。
📊 カーソル(埋め込みSQL)の基本情報
| 項目 | 内容 |
|---|---|
| 英語名 | Cursor(Embedded SQL) |
| 分類 | 埋め込みSQL(Embedded SQL)のデータ操作機能 |
| 4つの操作 | DECLARE CURSOR → OPEN → FETCH → CLOSE |
| 利用場面 | CやCOBOLなどの手続き型言語にSQL文を埋め込んでDB操作するとき |
解説
SQLは本来「集合」を扱う言語です。SELECT文を実行すると結果は「表(複数行のセット)」として返されます。しかし、CやCOBOLなどの手続き型言語は表データをそのまま受け取る構文を持っていません。
変数に格納できるのは基本的に「1行分のデータ」だけです。
この「集合を扱うSQL」と「1行ずつしか処理できないホスト言語」のギャップを埋めるのがカーソルの役割です。
埋め込みSQLとは
埋め込みSQL(Embedded SQL)とは、CやCOBOLなどのホスト言語のソースコード内に直接SQL文を記述する手法です。
SQL文の前後を「EXEC SQL」と「END-EXEC」で囲み、プリコンパイラが実行可能な形式に変換します。
この埋め込みSQLでSELECT結果が1行だけなら、INTO句でホスト変数に直接格納できます。しかし結果が複数行になる場合、INTO句では受け取れません。
ここでカーソルが必要になります。
DECLARE → OPEN → FETCH → CLOSE の4ステップ
カーソル操作は必ず以下の4ステップで行います。順序を崩すことはできません。
| 順 | SQL文 | 役割 |
|---|---|---|
| 1 | DECLARE CURSOR | カーソルを宣言し、対象となるSELECT文を定義する。この時点ではまだ問合せは実行されない |
| 2 | OPEN | カーソルを開き、SELECT文を実行して結果セット(導出表)を確定する |
| 3 | FETCH | カーソルが指す現在行のデータをホスト変数に取り出し、カーソルを次の行に進める。ループで繰り返す |
| 4 | CLOSE | カーソルを閉じ、結果セットが占有していたリソースを解放する |
図解:カーソル操作の流れ
| 手順 | やること | 表のイメージ | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ❶ DECLARE CURSOR |
読みたいデータを指定する (まだ読みに行かない) |
― 表はまだ手元にない ― | ||||||||||||
| ❷ OPEN | データを取りに行く (表が手元に届く) |
▶ はまだどこも指していない |
||||||||||||
| ❸ FETCH 繰り返し |
1行目を読む |
|
||||||||||||
| 2行目を読む |
|
|||||||||||||
| 3行目を読む → 次はもう無い → 終了 |
|
|||||||||||||
| ❹ CLOSE | 表を片付ける | ― 表は手元からなくなる ― |
コード例:埋め込みSQLでのカーソル操作
実際のコードイメージを確認しておくと理解が定着します。以下はC言語風の擬似コードです。
/* ① カーソルの宣言 */ EXEC SQL DECLARE cur_emp CURSOR FOR SELECT emp_id, emp_name, salary FROM employee WHERE dept = 'SALES'; /* ② カーソルを開く */ EXEC SQL OPEN cur_emp; /* ③ 1行ずつ取り出す(ループ) */ while(1) { EXEC SQL FETCH cur_emp INTO :h_id, :h_name, :h_salary; if (SQLCODE != 0) break; /* ホスト変数 h_id, h_name, h_salary を使った処理 */ printf("%d %s %d\n", h_id, h_name, h_salary); } /* ④ カーソルを閉じる */ EXEC SQL CLOSE cur_emp;
ポイントは3つです。
EXEC SQL〜で囲むのが埋め込みSQLの書式であること、FETCH文のINTO句でホスト変数(先頭にコロンを付けた変数)にデータを受け渡すこと、そしてSQLCODEの戻り値でループの終了を判定することです。
CURRENT OF による更新・削除
カーソルは検索だけでなく、現在行の更新や削除にも使えます。
WHERE句に「CURRENT OF カーソル名」を指定すると、FETCHで取り出した行をピンポイントで変更できます。
/* カーソルが指す行を更新 */ EXEC SQL UPDATE employee SET salary = salary * 1.1 WHERE CURRENT OF cur_emp; /* カーソルが指す行を削除 */ EXEC SQL DELETE FROM employee WHERE CURRENT OF cur_emp;
会話型SQLとの違い
カーソルは埋め込みSQLでのみ使う仕組みです。対話的にSQL文を実行する「会話型SQL」ではカーソルを意識する必要はありません。
会話型SQLでは結果セットが画面にそのまま表示されるため、1行ずつ取り出す操作が不要だからです。
| 比較項目 | 埋め込みSQL | 会話型SQL |
|---|---|---|
| 実行方法 | ホスト言語のソースコードに記述し、プリコンパイル後に実行 | 端末やツールから直接SQL文を入力して実行 |
| カーソルの使用 | 複数行の結果取得に必須 | 不要(結果はそのまま画面に表示される) |
| ホスト変数 | 使用する(コロン付き変数名) | 使用しない |
では、この仕組みが試験でどのように出題されるか見ていきましょう。
💡 カーソル(埋め込みSQL)の核心を3行で
・SELECT結果(複数行)を1行ずつホスト言語に渡すための仕組み
・操作順は DECLARE CURSOR → OPEN → FETCH(ループ)→ CLOSE の4ステップ
・会話型SQLでは不要であり、埋め込みSQL固有の機能
試験ではこう出る!
カーソルは、応用情報技術者の午前問題で数年おきに出題されています。基本情報技術者でも同一問題が流用されるケースがあり、データベーススペシャリストでは午前IIで定番のテーマです。
📊 過去問での出題実績
| 試験回 | 出題内容 | 問われたポイント |
|---|---|---|
| AP H25春 午前 問29 |
導出表を1行ずつ親プログラムに引き渡す操作と関係の深い字句を選ぶ | ・正解は「CURSOR」 ・ORDER BY、UNION、UNIQUEがひっかけ |
| AP H27春 午前 問27 |
上記H25春問29と同一の問題(流用) | ・APでは同じ問題が繰り返し出題される典型パターン |
| FE H30春 午前 問28 |
埋め込みSQLのコードを示し「Xは何を表す名前か」を問う | ・DECLARE X CURSOR → OPEN X → FETCH X → CLOSE X の流れからXがカーソルだと判断させる |
| DB H30春 午前II 問6 |
UPDATE文のWHERE句に入る字句を選ぶ | ・正解は「CURRENT OF カーソル名」 ・列名や表名をひっかけに使用 |
| DB H25春 午前II 問8 |
カーソルの説明として適切なものを選ぶ | ・正解は「埋め込み型SQLで使用し、会話型SQLでは使用できない」 ・「親言語内で使用できない」「検索用にだけ使用可能」がひっかけ |
📝 IPA試験での出題パターン
パターン1:「CURSORに関係する字句を選べ」
「導出表を1行ずつ親プログラムに引き渡す操作」という説明文が出題され、CURSOR・ORDER BY・UNION・UNIQUEの4択から選ばせる形式。キーワードは「1行ずつ」「親プログラム」。
パターン2:「コード中のXは何か」
DECLARE X CURSOR → OPEN X → FETCH X → CLOSE Xという埋め込みSQLのコード断片を見せ、Xがカーソル・スキーマ・テーブル・ビューのどれかを答えさせる形式。DECLARE CURSORの構文を知っていれば即答できる。
パターン3:「CURRENT OFの穴埋め」(DB向け)
UPDATE文またはDELETE文のWHERE句に「CURRENT OF カーソル名」を埋めさせる形式。データベーススペシャリストで繰り返し出題されている。
APレベルではパターン1・2を押さえておけばOKです。CURRENT OFまで問われるのはDBスペシャリストの範囲なので、深追いは不要です。
【確認テスト】理解度チェック
ここまでの内容を理解できたか、簡単なクイズで確認してみましょう。
Q. 埋め込みSQLにおいて、問合せによって得られた導出表を1行ずつ親プログラムに引き渡す操作と、最も関係の深いものはどれでしょうか?
- A. ORDER BY ―― 抽出したデータを特定の列の値で昇順または降順に並び替える句
- B. UNION ―― 複数のSELECT文の結果を併合して1つの結果セットにまとめる演算子
- C. CURSOR ―― SELECT文の結果セットに対してポインタを設定し、FETCH文で1行ずつデータを取り出す仕組み
正解と解説を見る
正解:C
解説:
CURSORは、埋め込みSQLで複数行の問合せ結果を1行ずつホスト言語に引き渡すための仕組みです。DECLARE CURSOR → OPEN → FETCH → CLOSE の順で操作します。
選択肢AのORDER BYは、結果セットの並び替えを指定する句であり、行の引き渡し方法とは関係ありません。選択肢BのUNIONは、複数のSELECT文の結果を合体させる集合演算子であり、こちらも1行ずつの引き渡し操作には該当しません。
よくある質問(FAQ)
Q. JavaやPythonでもカーソルを使いますか?
使います。ただし仕組みが異なります。JavaのJDBCではResultSetオブジェクト、PythonのDB-APIではcursorオブジェクトが同等の役割を果たしますが、これらはライブラリ側が提供するAPIであり、埋め込みSQLのようにソースコード中にSQL文を直接記述するものではありません。IPA試験でカーソルが問われる場合は「埋め込みSQL(CやCOBOLが前提)」の文脈です。
Q. FETCHで取り出す行がなくなったら何が起きますか?
SQLCODEに「データなし」を示す値(標準では100)がセットされます。プログラム側はこのSQLCODEの値をチェックしてループを抜ける処理を記述します。AP H28秋の午後問6(データベース)でも、FETCH後に「取り出す行がない場合には処理の繰返しを抜ける」という流れが出題されており、この仕組みの理解が前提となっていました。
Q. ストアドプロシージャ内のカーソルと埋め込みSQLのカーソルは同じものですか?
概念としては同じ「結果セットを1行ずつ処理する仕組み」ですが、動作環境が異なります。埋め込みSQLのカーソルはホスト言語側で動作し、プリコンパイラによってSQL文が変換されます。ストアドプロシージャのカーソルはDBMS内部で動作し、PL/SQLやTransact-SQLなどの手続き型拡張言語で制御します。IPA試験では両者を明確に区別する出題はほぼないため、試験範囲では深掘りされません。
Q. 「導出表」とは何ですか?
導出表とは、SELECT文の実行結果として生成される仮想的な表のことです。データベースに実体として保存されているわけではなく、問合せのたびに動的に作られます。カーソルはこの導出表に対してポインタを設定し、行を順番に取り出していきます。ビュー(VIEW)も導出表の一種ですが、ビューはCREATE VIEWで定義を保存する点が異なります。