日期:2014-05-16 浏览次数:20500 次
我们知道序列是和当前会话有关联的,譬如:
12:20:53 OE@orcl> CREATE SEQUENCE empseq 12:21:01 2 START WITH 100 12:21:01 3 INCREMENT BY 1 12:21:01 4 ORDER NOCYCLE; 序列已创建。 已用时间: 00: 00: 00.03 12:21:01 OE@orcl> 12:21:01 OE@orcl> SELECT empseq.CURRVAL FROM dual; SELECT empseq.CURRVAL FROM dual * 第 1 行出现错误: ORA-08002: 序列 EMPSEQ.CURRVAL 尚未在此会话中定义 已用时间: 00: 00: 00.03 12:21:19 OE@orcl> SELECT empseq.nextval FROM dual; NEXTVAL ---------- 100第一次必须先NEXTVAL一下得到当前值
,然后在同一个会话下你再使用此序列就没问题了。
在11gR2 oracle使用了一个deferred segment新技术,也就是创建表的时候,不会立即创建,而是延时到插入值的时候才开始创建,这样带来的好处是,建表速度快,而且不占资源,但是却带来一些问题,譬如我们将要讨论的插入序列问题。
如下:
11:48:58 CRY@orcl> create sequence seq_tt; 序列已创建。 已用时间: 00: 00: 00.03 11:49:09 CRY@orcl> create table test(id number,ss varchar2(100)); 表已创建。 已用时间: 00: 00: 00.01 11:49:17 CRY@orcl> select seq_tt.nextval from dual; NEXTVAL ---------- 1 已用时间: 00: 00: 00.00 11:49:28 CRY@orcl> insert into test values(seq_tt.nextval,'test test'); 已创建 1 行。 已用时间: 00: 00: 00.04 11:49:36 CRY@orcl> select * from test; ID SS ---------- ------------------------ 3 test test
很糟糕的,序列seq_tt跳过了2,直接把3插入到了表中。
我们来取消deferred segment这个特性再来试试(注意:11gr2中此值默认为TRUE的)
13:08:25 CRY@orcl> create sequence seq_tt; 序列已创建。 已用时间: 00: 00: 00.01 13:09:09 CRY@orcl> create table test(id number,ss varchar2(100)); 表已创建。 已用时间: 00: 00: 00.20 13:09:12 CRY@orcl> insert into test values(seq_tt.nextval,'test test'); 已创建 1 行。 已用时间: 00: 00: 00.01 13:09:19 CRY@orcl> select * from test; ID SS ---------- --------------------------------- 1 test test
当我们取消延时创建表之后,序列插入正常了。