第12章 順序(補足)

1.順序とは?

■順序(シーケンス)とは?

 データベースは複数の人間が同じデータを同時にアクセスして使用する。例えば注文データを格納する「注文表」は10人以上のオペレータがデータを登録する場合、注文データには一意の通し番号を振りたい。
 順序は、異なる数値を連続して高速に作成するオブジェクトである。このオブジェクトを利用し、主キー制約や一意キー制約を満たす値を自動的に入力することができる。
(Accessのオートナンバー型と同じ)

■順序の特徴・利用目的

  1. 順序を使えば、トランザクションやセッションに関係なく、要求(INSERT文)に応じて値を生成する。
  2. 関数やプログラムを使って連続番号を生成するよりも高速に作成できる。(パフォーマンスがあがる)

《順序を使わない場合の連続番号発生例》

INSERT INTO emp(empno, name) VALUES ( (SELECT MAX(id)+1 FROM emp), 'TOM');

※この例では、データが1件も入ってない場合にidがNULLになってしまう。
(MAX(NVL(id,0))+1でも同じ)

2.順序の作成

■構文

CREATE SEQUENCE 順序名
 [START WITH 初期値]
 [INCREMENT BY 増分]
 [MAXVALUE 最大値 / NOMAXVALUE]
 [MINVALUE 最大値 / NOMINVALUE]
 [CYCLE / NOCYCLE]
 [CASHE メモリにとる値 / NOCASHE];
START WITH
順序の最初の値を設定。昇順の場合は最小値、降順の場合は最大値と同じ値。デフォルトは「1」。
INCREMENT BY
順序の増分を指定。デフォルトは「1」。負の値を指定することで順序を降順に作成することもできる。
MAXVALUE / NOMAXVALUE
順序の最大値を指定。デフォルトはNOMAXVALUE。その場合、最大値は昇順なら「1027」に、降順なら「−1」にそれぞれ設定される。
MINVALUE / NOMINVALUE
順序の最小値を指定。デフォルトはNOMINVALUE。その場合、最小値は昇順なら「1」に、降順なら「−1027」にそれぞれ設定される。
CYCLE / NOCYCLE
順序が最大値(降順の場合は最小値)に達した後に引き続き最小値(降順の場合は最大値)から値を生成させる場合に利用。デフォルトはNOCYCLE。
CASHE / NOCASHE
指定された数だけ順序の値をメモリ上に格納する。デフォルトは「CASHE 20」。NOCASHEを指定すると、メモリ上に確保しない。

《作成例》

1から始まって9999まで1つずつ増えていく順序を作成する。

CREATE SEQUENCE seq_empno
 MAXVALUE 9999;

3.順序の確認

■順序を確認するデータ・ディクショナリ

USER_SEQUENCES , ALL_SEQUENCES , DBA_SEQUENCES
順序名と作成時のパラメータ、現在の値などがわかる。

《データ・ディクショナリの列》

列名内容
SEQUENCE_OWNER順序の持ち主(USER_SEQUENCESにはない列)
SEQUENCE_NAME順序名
MIN_VALUE最小値
MAX_VALUE最大値
INCREMENT_BY初期値
CYCLE_FLAG「C」ならCYCLE、「N」ならNOCYCLE
ORDER_FLAG???
CACHE_SIZEキャッシュする数
LAST_NUMBER最後に発行した番号

4.順序の使用方法

■順序名.NEXTVAL

指定した順序の次の値を参照する。

SELECT seq_deptno.NEXTVAL FROM dual;

■順序名.CURRVAL

現在のセッションで、最後に使った順序の値を参照する。

SELECT seq_deptno.CURRVAL FROM dual;

《使用例》

1.表を作成
CREATE TABLE meibo (id NUMBER(2), name VARCHAR2(50), tel VARCHAR2(13));
2.順序を作成
CREATE SEQUENCE seq_meibo_id;
3.データを追加
INSERT INTO meibo(id, name) VALUES (seq_meibo_id.NEXTVAL, 'どこぞのだれ太郎');

5.順序の削除

■構文

DROP SEQUENCE 順序名;

■POINT

  1. 順序オブジェクトを削除するにはDROP SEQUENCEシステム権限が必要。

6.順序の補足説明

■一度発行した順序は、取り消すことができない

一度発行した順序番号は、ロールバックしても元には戻らない。そのため、ロールバック後に再度挿入処理を行うと、欠番が生じる。
(やっぱりAccessのオートナンバー型と同じ)

《使用例》

1.データを追加
INSERT INTO meibo(id, name) VALUES (seq_meibo_id.NEXTVAL, 'どこぞのだれ子'); ←idが2で登録されたとする(SELECT文で確認)
2.ロールバックしてみる
ROLLBACK; ←1のINSERT文が取り消される
3.データを再度追加
INSERT INTO meibo(id, name) VALUES (seq_meibo_id.NEXTVAL, 'どこぞのだれ子'); ←idが2ではなく3で登録される(SELECT文で確認)

《欠番がおこる原因》

1.ロールバックしたとき
ロールバックすると変更は取り消されるが、順序オブジェクトの内容は元には戻らない。そのため、一度使った値はロールバックしても使うことはできない。
2.データベースが異常終了したとき
順序を作成すると、キャッシュ内に指定した数(デフォルトは20個)の値が保持され、データ追加時はキャッシュ内の値を順番に使っていく。データベースが異常終了するとキャッシュ内のデータが破壊されるため、再起動後はキャッシュしていた値の最大の次の値から生成される。
(キャッシュさせなければこの現象は起きないが、パフォーマンスは低下する)

練習問題

問題1

1から1ずつ増え、最高値999999まで到達するとそのまま値が変化しない順序を作成する場合の最適なSQL文を選べ。

  1. CREATE SEQUENCE seq1 MAXVALUE 999999;
  2. CREATE SEQUENCE seq1 START WITH 1 MAXVALUE 999999 STEP 1;
  3. CREATE SEQUENCE seq1 START WITH 1 MAXVALUE 999999 CYCLE;
  4. CREATE SEQUENCE seq1 MINVALUE 1 MAXVALUE 999999 NOCYCLE;
  5. CREATE SEQUENCE seq1 START WITH 1 MAXVALUE 999999 CASHE;

問題2

以下のSQL文を実行した。

CREATE SEQUENCE _seq
 INCREMENT BY 1
 START WITH 50
 MAXVALUE 100
 CYCLE
 CASHE 10;

正しい説明を選べ。

  1. この順序の初期値は1である
  2. この順序が100まで番号を生成すると、次の値は生成されずにエラーになる
  3. CASHE句を省略すると、NOCASHEを指定したことになる
  4. この順序は、UNIQUE条件を必ず満たす
  5. この順序は、1つの表でのみ使用できる
  6. この順序の増分は1である

[ TOP ]