S-JIS[2010-07-24/2010-12-29] 変更履歴

シーケンス(順序)

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;

SQLメモへ戻る / 情報照会へ戻る / Oracle目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま