Oracleのシーケンス(順序)オブジェクトのメモ。
|
create sequence シーケンス名 start with 初期値 increment by 増分 maxvalue 最大値 nocycle cache キャッシュ数 noorder ;
構文 | 概要 | 省略時のデフォルト値 |
---|---|---|
start with 値 | 一番最初の値 | 昇順の場合は最小値 降順の場合は最大値 |
increment by 値 | 増分(正の数なら昇順、負の数なら降順) | 1 |
minvalue 値 nominvalue |
最小値 nominvalueの場合、昇順なら1、降順なら-1026 |
nominvalue |
maxvalue 値 nomaxvalue |
最大値 nomaxvalueの場合、昇順なら1027、降順なら1 |
nomaxvalue |
cycle nocycle |
サイクル(循環)するかどうか。 cycleの場合、昇順なら最大値に達すると最小値に戻る。 nocycleの場合、昇順なら最大値に達した後にさらに値を取得しようとするとエラーになる。 |
nocycle |
chache 値 nochache |
メモリー上に採番した値を保持(キャッシュ)しておく個数。 キャッシュから値を取得できる場合はキャッシュしない場合より高速になる。 Oracleを再起動するとキャッシュしていた値は破棄されるので、番号は跳ぶ。 |
20 |
order noorder |
順序通りに値を返すかどうか。 orderにしない場合、シーケンスを要求した順と値の大小は無関係になる。 |
noorder |
CURRVAL擬似列・NEXTVAL擬似列でシーケンスの値を取得できる。
CURRVALで現在の値を取得する。一度も採番されていない場合はエラーになる。
SQL> select test_seq.currval from dual; select test_s2.currval from dual * 行1でエラーが発生しました。: ORA-08002: 順序TEST_S2.CURRVALはこのセッションではまだ定義されていません
NEXTVALで新規採番した値を取得する。
SQL> select test_seq.nextval from dual; NEXTVAL ---------- 1
SQL> insert into EMP (EMPNO) values(test_seq.nextval); 1行が作成されました。
シーケンスは、複数のセッション(コネクション)から同時に新しい値を取得しても重複しない値が採番されるので、トランザクションの対象外となっている。
したがって、個々のセッション(コネクション)内でロールバックしても、採番された値は元に戻らない(番号は再使用されない)。
→insertのreturning句を使って、採番された値を取得することが出来る
→JDBCでinsert時に採番された値を取得する例
現在のシーケンスの値を変更する直接の方法は無いが、NEXTVAL擬似列とALTERによる定義変更を使って変更することは出来るようだ。[2010-12-29]
参考: SHIFT the Oracleのシーケンスの現在値を再設定する
-- 現在値を30に変更する例 select 30 - シーケンス名.nextval - 1 from dual; alter sequence シーケンス名 increment by -23; --表示された値を指定 select シーケンス名.nextval from dual; --実際に値を変更する alter sequence シーケンス名 increment by 1; --増分を元に戻す --これで、次のnextvalは30になる
この方法はいくつかのステップを踏む(ALTER文を使っているので途中で暗黙にコミットされるし、そもそもシーケンスの採番は別トランザクションで行われる)ので、
テスト環境など、途中でシーケンスにアクセスされないことが保証されている環境でないと危ないだろう。
SQL*Plusの置換変数やバインド変数を使って機械的に出来るよう手順化すると、以下のような感じ。
def SEQNAME = シーケンス名 def NEWVAL = 新しい値 def INC = 1 --このシーケンスの増分(select increment_by from all_sequences where sequence_name=upper('&SEQNAME');で確認可能) var DIFF number exec select &NEWVAL - &SEQNAME..nextval - &INC into :DIFF from dual; exec execute immediate 'alter sequence &SEQNAME increment by '||:DIFF; select &SEQNAME..nextval from dual; alter sequence &SEQNAME increment by &INC;