在许多的数据库之中都会存在一种自动增长列的概念。像 SQL Server、MySQL、DB2都提供有这样的数据类型,可是惟独在Oracle之中没有(Oracle12C之后提供了,之前没有),但是在Oracle之中提供的是一种手工的自动增长列控制,而这样的控制在Oracle之中使用序列(对象)完成。如果要想进行序列的创建,则要使用如下的语法:
CREATE SEQUENCE 序列名称
[INCREMENT BY 步长] [START WITH 开始值]
[MAXVALUE 最大值 | NOMAXVALUE]
[MINVALUE 最小值 | NOMINVALUE]
[CYCLE | NOCYCLE]
[CACHE 缓存大小 | NOCACHE]
如果用户直接使用“CREATE SEQUENCE序列名称”创建的是一个默认序列,默认序列的数值从1开始,每次增长1,而且没有最大值,最小值为1
范例:创建一个默认的序列
CREATE SEQUENCE myseq ;
既然序列属于数据库对象,那么所有的数据库对象一定要保存在数据字典之中,序列的数据字典应该查“user_sequences”数据字典:
SELECT * FROM user_sequences ;
在此数据字典之中主要包含如下列的数据信息:
· SEQUENCE_NAME:表示的序列名称,本处为 MYSEQ;
· MIN_VALUE:表示序列的最小值,默认的序列最小值是 1;
· MAX_VALUE:表示序列的最大值,默认序列是没有最大值,10 28 已经很大了。
· INCREMENT_BY:步长,每次增长的数据,默认的是 1;
· CYCLE:是否为循环序列,如果是 N 表示非循环,如果是 Y表示循环;
· ORDER:表示序列是否排序;
· CACHE_SIZE :序列的缓存数据;
· LAST_NUMBER :序列最后一次的增长值。
当一个序列对象已经创建完成之后,那么下面就可以采用如下的两个伪列来进行序列的控制:
· 取得序列下一个增长数据(每次调用序列值都增长指定的步长): 序列.nextval;
· 取得序列的当前数据(每次调用序列都不增长): 序列.currval;
·在使用 currval 之前一定要首先使用 nextval,否则会出现“ORA-08002: 序列 MYSEQ.CURRVAL 尚未在此会话中定义”。
范例:操作序列
SELECT myseq.nextval FROM dual ;
SELECT myseq.currval FROM dual ;
解释:关于 user_sequences 数据字典之中的 LAST_NUMBER 和 CACHE 的作用
首先必须明确的是,LAST_NUMBER 并不是当前序列真正增长的数据。
实际上当用户每次进行数据增长控制的时候,LAST_NUMBER 都表示已经处理完的一批序列内容,当当前序列的数值等于了 LAST_NUMBER 数据时,那么会自动再增加指定个“CACHE”大小的序列。
但是由于数据存在有缓存的问题,所以当数据库重新启动之后,那么所操作的序列就可能出现跳号的情况。如果想要避免跳号问题出现,那么最简单的做法是取消缓存,使用 NOCACHE 表示。
现在序列已经创建完成,而且也已经可以正常的进行使用了,可是该如何实现行的自动编号呢?只能够在数据增加的时候手工的进行控制。
范例:建立数据表,同时保存数据
DROP TABLE mytab PURGE ;
CREATE TABLE mytab(
mid NUMBER ,
title VARCHAR2(50) ,
CONSTRAINT pk_mid PRIMARY KEY(mid)
) ;
INSERT INTO mytab(mid,title)
VALUES (myseq.nextval,'JAVA') ;
在开发之中只能够通过以上的方式实现序列的自动增长操作。
以上的序列创建方式是最为常用的一种方式,而现在也可以通过一些选项的控制,实现一些特殊的序列定义。
1,改变序列增长的步长
默认的序列步长是 1(INCREMENT BY 属性决定的)。
DROP SEQUENCE myseq ;
CREATE SEQUENCE myseq
INCREMENT BY 2 ;
此时每当调用 nextval 访问序列的时候,都会按照 2 进行数据的增长。
2 ,改变序列的开始值
默认的序列开始值是从 1 开始的,但是现在如果希望做一些定单的自动编号生成,则可以使用开始值设置一个较大的数据,这样处理定单编号就比较方便。
DROP SEQUENCE myseq ;
CREATE SEQUENCE myseq
INCREMENT BY 2
START WITH 10000000000000000000;
SELECT TO_CHAR(myseq.nextval,999999999999999999999)
3 ,循环序列
如果说现在希望序列的内容在:1、3、5、7、9 五个数据之间循环显示,那么就需要设置循环序列,而此时需要:
· 序列的最大值是 9;
· 序列的最小值是 1;
· 步长应该为 2。
DROP SEQUENCE myseq ;
CREATE SEQUENCE myseq
INCREMENT BY 2
START WITH 1
MAXVALUE 9 MINVALUE 1
CYCLE NOCACHE;
而利用此方式实际上就可以定义一些简单的抽奖的种子数据。