内部キーを自動生成すべくOracleの自動採番機能を試します。11gまでのバージョンでは事前にシーケンスを作成しておいて、insertのタイミングでnextvalしていく方法がオーソドックスでしたが、先日あるトランザクションテーブルを新設する際に実装してみました。create tableで自動採番の定義をするわけですが内部的にはcreate tableのタイミングでシーケンスが作成されてこれがinsertの都度nextvalされていく仕組みです。基本的にはこれまで手動でやっていた方法と変わらないみたいですが、内部的に作成されたシーケンスに対してalter sequenceを発行する事はできないのでalter tableで変更する事となります。
またこの自動採番機能を適用したテーブルに対してinsert allは実質使えなくなる点も注意が必要ですね。こちらご参考にどうぞ。
create table で GENERATED ALWAYS/BY DEFAULT を定義します
IDENTITY列の文 | 説明 |
GENERATED ALWAYS AS IDENTITY | 常にシーケンス・ジェネレータによってIDENTITY値が指定されます。列の値は指定できません。 |
GENERATED BY DEFAULT AS IDENTITY | 列値を指定しないときは常に、シーケンス・ジェネレータによってIDENTITY値が指定されます。 |
GENERATED BY DEFAULT ON NULL AS IDENTITY | NULLの列値を指定すると、シーケンス・ジェネレータによって次のIDENTITY値が指定されます。 |
この表はOracleサイトから引用しています。
https://docs.oracle.com/cd/F37626_01/java-driver-table/creating-tables-identity-column.html
CREATE TABLE EX01
(
SID NUMBER(18,0)
--GENERATED ALWAYS AS IDENTITY
GENERATED BY DEFAULT AS IDENTITY
MINVALUE 1
MAXVALUE 999999999999999999
INCREMENT BY 1
START WITH 1
CACHE 100
ORDER
NOCYCLE
NOT NULL
,SNAME VARCHAR2(32 CHAR)
,BIRTHDAY DATE
,NOTE VARCHAR2(256 CHAR)
,PRIMARY KEY (SID)
)
;
CREATE TABLE EX01
(
SID NUMBER(18,0)
--GENERATED ALWAYS AS IDENTITY
GENERATED BY DEFAULT AS IDENTITY
MINVALUE 1
MAXVALUE 999999999999999999
INCREMENT BY 1
START WITH 1
CACHE 100
ORDER
NOCYCLE
NOT NULL
,SNAME VARCHAR2(32 CHAR)
,BIRTHDAY DATE
,NOTE VARCHAR2(256 CHAR)
,PRIMARY KEY (SID)
)
;
DBA_TAB_IDENTITY_COLSでカラム名と対応するシーケンスの関係を確認できます
IDENTITYで定義したカラムとシーケンスの関係はDBA_TAB_IDENTITY_COLSで確認できます。また、sequenceに関する情報を変更するにはalter sequenceではなく、alter tableでの変更になります。
select * from DBA_TAB_IDENTITY_COLS
;
select * from DBA_TAB_IDENTITY_COLS
;
DBA_SEQUENCESと結合するとシーケンス情報を確認できます
select t.OWNER,t.TABLE_NAME,t.SEQUENCE_NAME,s.CACHE_SIZE,s.LAST_NUMBER
from DBA_TAB_IDENTITY_COLS t inner join DBA_SEQUENCES s
on t.OWNER = s.SEQUENCE_OWNER and t.SEQUENCE_NAME= s.SEQUENCE_NAME
where t.TABLE_NAME ='EX01' and t.OWNER='SOONI'
;
select t.OWNER,t.TABLE_NAME,t.SEQUENCE_NAME,s.CACHE_SIZE,s.LAST_NUMBER
from DBA_TAB_IDENTITY_COLS t inner join DBA_SEQUENCES s
on t.OWNER = s.SEQUENCE_OWNER and t.SEQUENCE_NAME= s.SEQUENCE_NAME
where t.TABLE_NAME ='EX01' and t.OWNER='SOONI'
;
GENERATED ALWAYS の場合、「カラム値」を指定したINSERTはできない。
ALTER TABLE SOONI.EX01 MODIFY (SID GENERATED ALWAYS AS IDENTITY (START WITH 1000000000))
;
ALTER TABLE SOONI.EX01 MODIFY (SID GENERATED ALWAYS AS IDENTITY (START WITH 1000000000))
;
GENERATED BY DEFAULT の場合、「カラム値」を指定したINSERTが可能
ALTER TABLE SOONI.EX01 MODIFY (SID GENERATED BY DEFAULT AS IDENTITY (START WITH 1000000000))
;
ALTER TABLE SOONI.EX01 MODIFY (SID GENERATED BY DEFAULT AS IDENTITY (START WITH 1000000000))
;
自動採番カラムの追加
以下DDLでカラムの追加と、既存レコードが存在する場合自動採番した値を入れてくれます。
ALTER TABLE SOONI.EX01 add (SID NUMBER(18,0) GENERATED BY DEFAULT AS IDENTITY (START WITH 1000000000))
;
ALTER TABLE SOONI.EX01 add (SID NUMBER(18,0) GENERATED BY DEFAULT AS IDENTITY (START WITH 1000000000))
;
シーケンスキャッシュ値を変更する例
割り当たっているシーケンスのシーケンスキャッシュ値を変更する場合以下のようになります。
ALTER TABLE SOONI.EX01 modify (SID GENERATED BY DEFAULT AS IDENTITY (CACHE 300))
;
ALTER TABLE SOONI.EX01 modify (SID GENERATED BY DEFAULT AS IDENTITY (CACHE 300))
;