NEXTVAL 和 CURRVAL 运算符和oracle的sequence设置说明

本文深入解析了Oracle序列号的创建过程、使用方法及其关键特性,包括CURRVAL和NEXTVAL运算符的运用、并发访问机制、限制条件等。详细介绍了序列号在数据库排序场景中的应用,并提供了实例演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值