データベーススペシャリスト 2018年 午前2 問06
問題文
次のSQL文は、A表に対するカーソルBのデータ操作である。(a)に入れる字句はどれか。
UPDATE A
SET A2 = 1, A3 = 2
WHERE <b>(a)</b>
ここで、A表の構造は次のとおりであり、実線の下線は主キーを表す。
A(A1、A2, A3)
選択肢
ア:CURRENT OF A1
イ:CURRENT OF B(正解)
ウ:CURSOR B OF A
エ:CURSOR B OF A1
🔒 解説は解答すると表示されます
WHERE CURRENT OF句【午前2解説】
正解の理由
選択肢の中で、位置指定更新(positioned update)を行う標準的な書式は "WHERE CURRENT OF カーソル名" であり、カーソル名を指定してカーソルが現在指している行(カーソルの現在行)を更新します。したがって正しいのは イ の "CURRENT OF B" です。
ここで重要なのは、WHERE CURRENT OF が「カーソルが現在位置している行(行ロケータ)を指す」点であり、必ずしも主キー名を自動的に参照するものではないことです。実装によっては ROWID や内部の行ロケータを使って対象行を特定します。
ここで重要なのは、WHERE CURRENT OF が「カーソルが現在位置している行(行ロケータ)を指す」点であり、必ずしも主キー名を自動的に参照するものではないことです。実装によっては ROWID や内部の行ロケータを使って対象行を特定します。
解法ステップ
- SQL の標準的な構文を思い出す:位置指定更新は WHERE CURRENT OF cursor_name の形で書く。
- 選択肢を照合する:CURRENT OF の後には「カーソル名」が来るべきで、ここでのカーソル名は B(カーソルB)である。
- 他の選択肢は構文や意味が合致しないため除外する。
- よって イ を選ぶ。
選択肢別の誤答解説
- ア: CURRENT OF A1
- A1 は表 A の列名(主キー列)であり、CURRENT OF の後にはカーソル名が来るため文法的に不適切です。A1 がカーソル名として宣言されていない限り誤りです。
- イ: CURRENT OF B
- 正解。カーソル B が現在位置する行を指定する構文として正しい。UPDATE 文はこの行ロケータを使って正確に更新する。
- ウ: CURSOR B OF A
- SQL の UPDATE の WHERE 句において使う構文として無効です。"CURSOR ..." は宣言時のキーワードであり、ここで使える形ではありません。
- エ: CURSOR B OF A1
- 同上。さらに A1 は列名なので意味的にも成立しません。
よくある誤解
- 「WHERE CURRENT OF は主キーを自動的に使う」
- 誤り。WHERE CURRENT OF はカーソルが指す現在行を更新するための指定であり、行の特定には実装依存の行ロケータ(ROWID 等)を使うことが多いです。主キーを明示的に使うわけではありません。
- 「CURRENT OF の後にはテーブル名を置ける」
- 誤り。後にはカーソル名(宣言したカーソル識別子)を置きます。テーブル名や列名は不可です。
- 「カーソル宣言なしでも使える」
- 誤り。通常はそのカーソルを DECLARE して OPEN し、少なくとも一度 FETCH して現在行を得ている必要があります。また多くの実装ではカーソルを FOR UPDATE 指定で宣言していなければ位置指定更新ができません。
補足コラム
位置指定更新(positioned update/delete)は、検索結果を順に処理しながら当該行を直接更新・削除する場面で便利です。典型的なフローは次の通りです(擬似SQL):
-- 例(PL/SQL 等の手続き言語内)
DECLARE
CURSOR B IS SELECT A1, A2, A3 FROM A FOR UPDATE;
vA1 A.A1%TYPE;
vA2 A.A2%TYPE;
vA3 A.A3%TYPE;
BEGIN
OPEN B;
LOOP
FETCH B INTO vA1, vA2, vA3;
EXIT WHEN B%NOTFOUND;
-- 現在行を更新
UPDATE A SET A2 = 1, A3 = 2 WHERE CURRENT OF B;
END LOOP;
CLOSE B;
END;
実装差に注意:多くのRDBMSが WHERE CURRENT OF をサポートしますが、宣言の仕方や FOR UPDATE の要否、内部で行を特定する手段(主キー値 vs ROWID の利用)などは製品ごとに異なります。
FAQ
Q1: WHERE CURRENT OF の後に列名を置けば主キーで更新できるか?
A1: できません。WHERE CURRENT OF の後には「カーソル名」を置きます。もし主キー値で指定したいなら、WHERE A1 = :key_value のように主キー値を明示して更新します。
A1: できません。WHERE CURRENT OF の後には「カーソル名」を置きます。もし主キー値で指定したいなら、WHERE A1 = :key_value のように主キー値を明示して更新します。
Q2: カーソルを使わずに同じ行を更新するには?
A2: 主キーや一意制約のある列で条件を明示して UPDATE する方法があります(例: WHERE A1 = 123)。位置指定更新は「現在行」を直接扱いたい場合に使います。
A2: 主キーや一意制約のある列で条件を明示して UPDATE する方法があります(例: WHERE A1 = 123)。位置指定更新は「現在行」を直接扱いたい場合に使います。
Q3: カーソルを開いていないと WHERE CURRENT OF はどうなるか?
A3: カーソルが開かれておらず現在行が定まっていない場合はエラーになります。通常は OPEN→FETCH→(WHERE CURRENT OF)という順が必要です。
A3: カーソルが開かれておらず現在行が定まっていない場合はエラーになります。通常は OPEN→FETCH→(WHERE CURRENT OF)という順が必要です。
関連キーワード: SQL、カーソル、位置指定更新、WHERE CURRENT OF、ROWID、FOR UPDATE、行ロケータ、更新文

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

