Oracle序列生成器

  在生活中,我门会需要到一些自动增长的序列,例如记录编号、日志编号等,MySQL和SQL Server采用的是自增字段,Oracle和PostgreSQL采用了更灵活的序列生成器。在本文中,把序列生成器简称为序列。

一、创建序列

创建序列的语法如下:

create sequence 序列名
       [minvalue n]
       [maxvalue n]
       [increment by n]
       [start with n]
       [cache n|nocache]
       [order|noorder]
       [cycle|nocycle];

  参数说明:

  Oracle的序列分为递增序列和递减序列,递减序列极少使用(二十年我从未用过),为了方便介绍,本文假设序列是递增序列。

  序列名:序列名是标志符,建议’以SEQ_打头,例如为T_OPERLOG表的logid字段创建一个序列,可以把它 命名为SEQ_OPERLOG(或SEQ_OPERLOG_LOGID),增加数据结构的可读性,这是我的个人经验,并不是Oracle数据库的要求。

  [minvalue n]:序列的最小值,缺省值是1。

  [maxvalue n]:序列的最大值,缺省值是9999999999999999999999999999。

  [increment by n]:序列递增的步长,缺省值是1。

  [start with n]:序列的起始值,缺省值是minvalue,如果n小于minvalue,创建序列会报语法错误。

  [cache n|nocache]:是否采用缓存机制,nocache不采用缓存,缺省cache 20,数据库每次会生成20个值放在缓存中,如果缓存中有数据,就不需要再查数据库了,采用缓存机制可以提升效率。

  [order|noorder]:获取序列的时候是否按顺序给值,如果多用户一起获取序列的值,使用order可以保证序列值的顺序按访问序列的事件排序,缺省是noorder。

  [cycle|nocycle]:是否循环,缺省不循环,如果不循环,序列值到了maxvalue后将不可用。

二、序列的使用

1、创建最简单的序列

create sequence SEQ_GIRL;

  执行以上SQL语句会在数据库中生成一个名字为SEQ_GIRL的序列,除了序列名,其它的参数都采用缺省值,相当于以下SQL:

create sequence SEQ_GIRL 
       minvalue 1 
       maxvalue 9999999999999999999999999999 
       increment by 1 
       start with 1 
       cache 20 
       noorder  
       nocycle ;

2、在dual虚表使用序列

  序列创建后,用序列名.nextval获取序列的下一个值,用序列名.currval来查看当前值。

select SEQ_GIRL.nextval from dual;     -- 获取序列SEQ_GIRL的下一个值。
select SEQ_GIRL.currval from dual;     -- 获取序列SEQ_GIRL的当前值

  在新的会话中,必须先使用nextval来产生一个值后才可以使用currval进行查看。

在这里插入图片描述
在这里插入图片描述
  如果不先用 序列名.nextval 产生一个值,直接用 序列名.currval 来获取当前序列值就会报错。
在这里插入图片描述

3、在SQL语句中使用序列

  (1)我们先创建一个递增的序列。
在这里插入图片描述

  (2)创建一个简单的表

create table T_hero
(
  name    varchar2(10),     -- 姓名
  keyid   number(10)        -- 记录编号
);

1)在insert语句中使用序列。

insert into T_hero(name,Keyid) values('亚瑟',hero.nextval);
insert into T_hero(name,Keyid) values('妲己',hero.nextval);
insert into T_hero(name,keyid) values('卤蛋',hero.nextval);

执行结果:
在这里插入图片描述

2)在update语句中使用序列。

update T_hero set keyid=hero.nextval+10;

执行结果:
在这里插入图片描述

三、序列裂缝

1、序列不产生事务

序列的nextval方法不会产生事务,事务回滚命令rollback不会恢复序列的值,我们来做一个测试。

1)先获取序列的当前值。

在这里插入图片描述

2)执行一条不会成功的SQL语句。

在这里插入图片描述

3)再获取序列的当前值。
在这里插入图片描述
4)在往表中插入一条记录

在这里插入图片描述
5)查看表,新插入的记录的 keyid 为24 ,跳过了23(因为23刚刚插入失败时,被占用了)

在这里插入图片描述

2、序列裂缝

如果用序列的值作为表中某个字段的值,这个字段的值可能会出现不连续的情况。因为序列的值不连续,有裂缝。

序列在下列情况下出现裂缝:

1)执行SQL语句失败;

2)事务回滚;

3)序列缓存;

4)多个表同时使用同一序列;

5)其它异常。

四、修改序列

修改序列的语法如下:

alter sequence 序列名
     [minvalue n]
     [maxvalue n]
     [increment by n]
     [start with n]
     [cache n|nocache]
     [order|noorder]
     [cycle|nocycle];

修改序列的参数与创建序列的参数相同,不同的是,修改序列时没有缺省值。

下面我修改每次递增的值为5

alter sequence a increment by 5;

在这里插入图片描述
(1)查看当前的序列值
在这里插入图片描述
(2)查看下一个序列值,增加了5
在这里插入图片描述

五、删除序列

删除序列的语法如下:

drop sequence 序列名;

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值