已索引
什么是序列
序列是生成唯一整数值的结构,它的典型用途是用于主键值。
A sequence is a database object that creates integer values. You can create sequences and then use them to generate numbers.
A sequence:
- Can automatically generate unique numbers
- Can be used to create a primary key value
- Is a shareable object(序列是独立于表的,是全局唯一的,可以在多个表中去调用同一个序列,共享的意思,例如 HR 创建了一个序列并调用了,SYS 用户调用时将产生下一个值)
- Replaces application code(使用序列,就不用通过程序代码来实现产生递增数的功能了)
- Speeds up the efficiency of accessing sequence values when cached in memory
序列语法
CREATE SEQUENCE sequence
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE n| NOMAXVALUE}]
[{MINVALUE n| NOMINVALUE}]
[{CYCLE | NOCYCLE}]
[{CACHE n| NOCACHE}];
说明:
MINVALUE定义这个序列的最小值。对于一个递增序列(步长为正),如果一个cycle的序列增加到最大值,该序列会从最小值开始新的一轮循环,
MAXVALUE定义这个序列的最大值。对于一个递减序列(步长为负),如果一个cycle的序列减小到最小值,该序列会从最大值开始新的一轮循环。
例如:
SQL> create sequence myseq
increment by 2
start with 10
minvalue 5
maxvalue 40
cycle
nocache;
该序列从10开始,每次加2,加到40后,又从5开始,每次加2……
CYCLE定义这个序列是否循环。如果序列不CYCLE,达到最大值后,会报错。
CACHE n | NOCACHE Specifies how many values the Oracle server preallocates and keeps in memory (By default, the Oracle server caches 20 values.)
可以通过user_sequences视图来查看序列的详细信息。
NEXTVAL and CURRVAL Pseudocolumns
NEXTVAL returns the next available sequence value. It returns a unique value every time it is referenced, even for different users.
- 例如,一个会话的nextval是3,则另一个会话的nextval是序列的下一个值4。
- CURRVAL obtains the current sequence value.
- NEXTVAL must be issued for that sequence before CURRVAL contains a value.
注意:当同一个语句中多次调用NEXTVAL时,产生同一个值:
SQL> create sequence test_seq2;
SQL> select test_seq2.nextval from dual; // 返回1
SQL> insert into test_seq values(test_seq2.nextval,test_seq2.nextval);
SQL> select * from test_seq; // 两列都返回2
CURRVAL的注意事项:
Oracle官方文档上面关于CURRVAL的说法是这样的:
Any reference to CURRVAL always returns the current value of the sequence, which is the value returned by the last reference to NEXTVAL.
实际上,我们发现CURRVALUE是基于会话的,这个在 Oracle 文档 Concepts ---> 4 Partitions, Views, and Other Schema Objects 里也有说明:
Each user that reference a sequence has access to his or her current sequence number, which is the last sequence generated in the session.
A会话:
NEXTVAL: 5
CURRVAL: 5
B会话:
NEXTVAL: 6
CURRVAL: 6
A会话:
CURRVAL: 5
如果A会话先调用了一个NEXTVAL,则CURRVAL是7。
GAPS in sequence
Gaps in sequence values can occur when:
– A rollback occurs
– The system crashes
– A sequence is used in another table
修改序列
• You must be the owner or have the ALTER privilege for the sequence.
• Only future sequence numbers are affected.
• Change the increment value, maximum value, minimum value, cycle option, or cache option。但是不可以修改start with的值(除非删除重建)。
创建序列后可以使用alter命令再进行修改。alter命令和create命令基本相同,只有一点区别:alter命令不能设置起始值。如果要重启该序列,唯一的办法是删除并重新创建它。
使用序列
示例:有一张表emp记录员工编号和姓名,编号格式如2614032XX
SQL> create sequence student_id start with 1 increment by 1 maxvalue 32 nocycle;
SQL> insert into emp
values(to_number(concat('2614032',lpad(to_char(student_id.nextval),2,'0'))),'&student_name');
关于自增列
所谓的自增列,就是在建表时,指定这个列是一个自增加的列,Oracle 12c 之前没有自增列这一说,而是创建好一个表,然后在表的列上引用序列的值,以达到自增的目的。我们可以在用户层做限制,不提供用户输入使用序列值的列的值的接口,这样,就可以实现列值自增了。也可以定义一个函数来实现自增,在定义表列时指定“DEFAULT 函数名”,函数的基本思想是每次运行先得到表当前的最大值,然后加1,但是这样做性能不好。
12c开始可以定义一个自增列了(有待验证):
create table product (
product_id number generated as identity,
product_name varchar2(100) not null);
序列的几点说明
- 最简单的建立序列只需要 create sequence 序列名就可以,注意缺省值,起始是 1,步长也是1。
- 如果启用cache,缺省只有20个号,经验表明这个数量会不够,可以设置多一些,根据需要10000个也可以。
- cycle 会使序列发出重复值,这对于基于序列是主键值的用法是个问题。
- descending sequences that CYCLE must specify MINVALUE(即不能设置 nominvalue)
- ascending sequences that CYCLE must specify MAXVALUE(即不能设置 nomaxvalue)