Hitachi

ノンストップデータベース HiRDB Version 10 UAP開発ガイド


3.5.1 カーソルを使用して表を操作するときの留意事項

〈この項の構成〉

(1) カーソルの更新可能性,及びカーソルを使用した操作有無と,カーソルを使用しない操作との関連

カーソルを宣言,又は割り当てた後,OPEN文でカーソルを開くと,データを取り出して,参照や更新などの操作ができます。また,カーソル宣言中,並びにカーソル宣言に指定したSQL文識別子,及びカーソル割り当てに指定した拡張文名が識別する動的SELECT文中の,FOR READ ONLY句,又はFOR UPDATE句の指定の有無と,そのカーソルを使用した操作(更新,及び削除)の有無によって,カーソルを開いた後にカーソルを使用しない操作ができるかどうかが決まります。

カーソルの更新可能性とカーソルを使用しない操作との関連を次の表に示します。なお,SQL最適化オプションの更新SQLの作業表作成抑止を指定すると,カーソルを使用しない操作の制限が緩和されます。

表3‒27 カーソルの更新可能性とカーソルを使用しない操作との関連

条件

カーソルを使用しない操作

カーソルの更新可能性の指定

カーソルを使用した操作

SQL最適化オプションの更新SQLの作業表作成抑止を適用しない場合

SQL最適化オプションの更新SQLの作業表作成抑止を適用して,インデクスキー値無排他機能を使用

更新

削除

検索

更新

削除

追加

検索

更新

削除

追加

静的SQL

FOR READ ONLY句指定あり

なし

なし

FOR UPDATE OF 列名指定あり

なし

なし

×

×

※2

※2

※2

なし

あり

あり

なし

×

×

※2

※2

※2

あり

あり

FOR UPDATE句指定あり

なし

なし

なし

あり

あり

なし

あり

あり

上記の指定なし※1

なし

なし

×

×

×

※2

※2

※2

なし

あり

あり

なし

あり

あり

動的SQL

FOR READ ONLY句指定あり

なし

なし

FOR UPDATE OF 列名指定あり

なし

なし

×

×

※2

※2

※2

なし

あり

あり

なし

×

×

※2

※2

※2

あり

あり

FOR UPDATE句指定あり

なし

なし

なし

あり

あり

なし

あり

あり

上記の指定なし

なし

なし

×

×

×

※2

※2

※2

なし

あり

あり

なし

あり

あり

(凡例)

○:操作できます。

△:指定した列の更新ができます。

×:操作できません。

注※1

CURRENT OF カーソル名を指定した更新,又は削除が同一ポストソース内にある場合は,FOR UPDATEが仮定されます。

注※2

カーソルを使用した検索で使っているインデクスを更新した場合,カーソルでの検索結果は保証されません。例と対策方法を次に示します。

<例>
CREATE INDEX X1 ON T1(C1);
DECLARE CR1 CURSOR FOR SELECT C1 FROM T1 WHERE C1>0;
 
宣言したカーソルを使用して,次のFETCH文,UPDATE文を繰り返し実行します。
 
FETCH CR1 INTO :XX;
UPDATE T1 SET C1=10;
 
C1=10に更新した行が再度検索されます。
<対策方法>

次のどちらかの対策をしてください。

  • UPDATE文の更新値が,検索の探索条件を満たさないように探索条件を変更してください。

    (例)WHERE C1>0 AND C1 <>10

  • 検索に使用するインデクスの構成列から,該当する列を削除してください。ただし,インデクス構成列の一部を削除した場合,その列が探索条件で十分に絞り込める列だったときは,性能が劣化するので注意してください。また,インデクス構成列の一部を削除した場合,インデクスキーの重複数が多くなり,排他待ち,及びデッドロックの多発を招くおそれがあるため,注意してください。したがって,この対策をする場合には,十分に検証した上で採用するようにしてください。

(2) 二つ以上のカーソルを同時に使用する場合

二つ以上のカーソルを使用して同じ表を同時に更新する場合,それぞれのカーソル宣言,又は動的SELECT文のFOR UPDATE句の列名の並びに,更新する列をすべて指定します。例えば,カーソル1で列1を更新し,カーソル2で列2を更新する場合,カーソル1,及びカーソル2を宣言するときに,FOR UPDATE句に列1,及び列2の両方を指定します。カーソル1で列1だけ,カーソル2で列2だけを指定した場合,更新時にエラーになります。