在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方。
1、Create Sequence
你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE权限,
CREATE SEQUENCE emp_sequence
INCREMENT BY 1 --每次加几个
START WITH 1 --从1开始计数
NOMAXVALUE --不设置最大值
NOCYCLE --一直累加,不循环
CACHE 10;
一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL
CURRVAL=返回sequence的当前值
NEXTVAL=增加sequence的值,然后返回sequence值
比如:
emp_sequence.CURRVAL
emp_sequence.NEXTVAL
Create Sequence
你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE权限,
CREATE SEQUENCE emp_sequence
INCREMENT BY 1 -- 每次加几个
START WITH 1 -- 从1开始计数
NOMAXVALUE -- 不设置最大值
NOCYCLE -- 一直累加,不循环
CACHE 10; --缓存序列个数,有助于提高效率,但可能造成跳号。
- 如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,oracle自动再取一组到cache。 使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失. 所以可以在create sequence的时候用nocache防止这种情况。
NEXTVAL和CURRVAL运算符(IDS)
可以通过在SQL语句中使用NEXTVAL或CURRVAL运算符来访问序列的值。必须用以sequence.NEXTVAL或sequence.CURRVAL格式驻留在同一个数据库中的序列名称(或同义词)来限定NEXTVAL或CURRVAL。表达式也可以用所有者名来限定序列,如zelaine.myseq.CURRVAL。可以指定sequence的SQL标识或有效同义词(如果存在的话)。(这段现在还看不太懂,mark一下)
在符合ANSI的数据库中,如果您不是所有者,必须用所有者名(owner.sequence)限定序列名。
要对序列使用NEXTVAL或CURRVAL,必须对序列具有选择特权或对数据库具有DBA特权。关于序列级特权的信息,请参阅GRANT语句。
使用NEXTVAL
第一次访问一个序列,在引用sequence.CURRVAL之前必须先引用sequence.NEXTVAL。第一次引用NEXTVAL,返回序列的初始值。后面每次引用NEXTVAL,用已定义的step增加序列值并返回序列新的增加以后的值。
在一个SQL语句中只能对给定的序列增加一次。即使在一个语句中多次指定sequence.NEXTVAL,序列也只增加一次,所以每次sequence.NEXTVAL出现在同一SQL语句中返回相同的值。
除了在同一语句中多次出现这种情况以外,每个sequence.NEXTVAL表达式都会增加序列,无论后来是否提交或回滚当前事务。
如果在最终回滚的事务中指定sequence.NEXTVAL,某些序列数可能被跳过。
使用CURRVAL
任何对CURRVAL的引用返回指定序列的当前值,该值是最后一次对NEXTVAL的引用所返回的值。用NEXTVAL生成一个新值以后,可以继续使用CURRVAL访问这个值,不管另一个用户是否增加这个序列。
如果sequence.CURRVAL和sequence.NEXTVAL都出现在一个SQL语句中,则序列只增加一次。在这种情况下,每个sequence.CURRVAL和sequence.NEXTVAL表达式都返回相同的值,不管在语句中sequence.CURRVAL和sequence.NEXTVAL的顺序。
序列的并发访问
序列总是在数据库中生成唯一值,即使当多个用户并发地引用同一序列时也没有可察觉的等待或锁定。当多个用户使用NEXTVAL来增长序列时,每个用户生成一个其他用户不可见的唯一值。
当多个用户并发地增加同一序列时,每个用户看到的值是有差异的。例如,一个用户可能从一个序列生成一组值,如1、4、6和8,而另一个用户并发地从同一序列生成值2、3、5和7。
限制
NEXTVAL和CURRVAL只在SQL语句中有效,并不在SPL语句中直接有效。(但是使用NEXTVAL和CURRVAL的SQL语句可用于SPL例程。)以下限制应用于SQL语句中的这些运算符:
必须对序列有选择特权。
在CREATETABLE或ALTERTABLE语句中,在下列上下文中不能指定NEXTVAL或CURRVAL:
在DEFAULT子句中
在检查约束中。
在SELECT语句中,下列上下文中不能指定NEXTVAL或CURRVAL:
使用DISTINCT关键字时在投影列表中。
在WHERE、GROUPBY或ORDERBY子句中
在子查询中
在UNION运算符结合SELECT语句时。
在下列这些上下文中也不能指定NEXTVAL或CURRVAL:
在分段存储表达式中
在对另一个数据库中的远程序列对象的引用中。
示例
在下面的例子中,假设没有其它用户并发地访问序列并且用户连续执行语句。
示例基于下列序列和表:
CREATE SEQUENCE seq_2
INCREMENT BY 1 START WITH 1
MAXVALUE 30 MINVALUE 0
NOCYCLE CACHE 10 ORDER;
CREATE TABLE tab1 (col1 int, col2 int);
INSERT INTO tab1 VALUES (0, 0);
可以在INSERT语句的values子句中使用NEXTVAL(或CURRVAL),如以下示例中所示:
INSERT INTO tab1 (col1, col2)
VALUES (seq_2.NEXTVAL, seq_2.NEXTVAL)
在前面的例子中,数据库服务器把一个增加后的值(或序列的初始值,即1)插入到表的col1和col2列。
可以在UPDATE语句的SET子句中使用NEXTVAL(或CURRVAL),如以下示例中所示:
UPDATE tab1
SET col2 = seq_2.NEXTVAL
WHERE col1 = 1;
在前面的例子中,seq_2序列增长以后的值,即2,替换了col2中col1等于1的值。
以下示例显示了如何在SELECT语句的Projection子句中使用NEXTVAL和CURRVAL:
SELECTseq_2.CURRVAL,seq_2.NEXTVALFROMtab1;
在前面的示例中,数据库服务器从CURRVAL和NEXTVAL表达式返回两行增加后的值,3和4。对tab1的第一行,数据库服务器返回CURRVAL和NEXTVAL增加后的值3;对tab1的第二行,它返回增加后的值4。
假如在创建sequence时,有意不选用cache选项,有2点需要注意:
1. 访问效率降低,没有cache功能的sequence取值将无法直接访问内存
2. 不论是nocache还是cache , 每次访问nextval的过程都是不可逆的,在同一session中,在执行一系列dml和sequence的操作后,用户执行rollback,希望将操作回滚,但是sequence此时就显得异常顽固,用掉的nextval将无法被重现。当下一次试图读取nextval时,sequence的指针又移动到下一位了。
还有sequence不属于某个表,也不属于某个字段,sequence仅仅属于某个用户。
其实在创建了sequence后,每个表都可以使用这个sequence,但是这样会引起应用的很多麻烦,因此,建议每个表都使用一个sequence。