oracle序列问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle序列问题相关的知识,希望对你有一定的参考价值。

创建一个序列,序列的起始值为49,每次增加10,直到200,然后重新从59开始

这和序列的cache有关,默认cache为20,也就是每次拿出20个放到内存中,当实例崩溃或者内存清洗后则会发生断号的情况。如果你想解决这个问题,可以设置序列的cache为1
--------------------------------
在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
可以使用sequence的地方:
-
不包含子查询、snapshot、VIEW的
SELECT
语句
-
INSERT语句的子查询中
-
NSERT语句的VALUES中
-
UPDATE

SET中
可以看如下例子:
INSERT
INTO
emp
VALUES
(empseq.nextval,
'LEWIS',
'CLERK',7902,
SYSDATE,
1200,
NULL,
20);
SELECT
empseq.currval
FROM
DUAL;
但是要注意的是:
-
第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT
BY值,然后返回增加后的值。CURRVAL
总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白?
-
如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,oracle自动再取一组到cache。
使用cache或许会跳号,
比如数据库突然不正常down掉(shutdown
abort),cache中的sequence就会丢失.
所以可以在create
sequence的时候用nocache防止这种情况。
2、Alter
Sequence
你或者是该sequence的owner,或者有ALTER
ANY
SEQUENCE
权限才能改动sequence.
可以alter除start至以外的所有sequence参数.如果想要改变start值,必须
drop
sequence

re-create
.
Alter
sequence
的例子
ALTER
SEQUENCE
emp_sequence
INCREMENT
BY
10
MAXVALUE
10000
CYCLE
--
到10000后从头开始
NOCACHE
;
影响Sequence的初始化参数:
SEQUENCE_CACHE_ENTRIES
=设置能同时被cache的sequence数目。
可以很简单的Drop
Sequence
DROP
SEQUENCE
order_seq;
参考技术A 序列即sequence。
Sequence是数据库系统。这个序列一般作为代理主键(因为不会重复),没有其他任何意义。
Sequence是数据库系统的特性,有的数据库实现了Sequence,有的则没有。比如Oracle、DB2、PostgreSQL数据库实现Sequence,mysql、SQL
Server、Sybase等数据库没有Sequence。
创建方法:
CREATE SEQUENCE emp_sequence --序列名
INCREMENT BY 1 -- 每次加几个
START WITH 1 -- 从1开始计数
NOMAXVALUE -- 不设置最大值
NOCYCLE -- 一直累加,不循环
CACHE 10;
参考技术B 因为start with参数的值不能小于 minimum参数的值
而cycle又是从minimum参数开始循环的
所以你的问题还是蛮刁的

如果你主要目的是从59到200的循环
我建议你不如在需要插入序列的地方先手工设置一个49的值
然后再用一个59-200的序列
那至少运行起来不用再手工干预了

如果你的目的是每轮的起始值+10
那么很遗憾
简单的sequence已经不能满足你的要求了

建一个存储过程吧本回答被提问者采纳
参考技术C create sequence t_seq
increment by 10
start with 49
maxvalue 200
minvalue 49
cycle
cache 15

1楼完全没经过测试,cache参数默认20,cache必须小于cycle的值。
后面从59开始还真没想出来
如果实在没办法只能人工干预了
SQL> insert into t
2 select t_seq.nextval from dual;

SQL> select * from t;

ID
----------
49
59
69
79
89
99
109
119
129
139
149

ID
----------
159
169
179
189
199

已选择16行。

SQL> insert into t
2 select t_seq.nextval+10 from dual;

已创建 1 行。

SQL> select * from t;

ID
----------
49
59
69
79
89
99
109
119
129
139
149

ID
----------
159
169
179
189
199
59

已选择17行。

SQL> insert into t
2 select t_seq.nextval+10 from dual;

已创建 1 行。

SQL> select * from t;

ID
----------
49
59
69
79
89
99
109
119
129
139
149

ID
----------
159
169
179
189
199
59
69

已选择18行。

SQL>
参考技术D 起始值为49,然后重新从49开始的代码如下:

CREATE SEQUENCE name
INCREMENT BY 10
START WITH 49
MAXVALUE 200
MINVALUE 49
CYCLE

oracle序列

创建序列

create sequence mysequence  
increment by 1  
start with 1   -- oracle 10g好像 nextval取到的第一个数是2,11g就没有这个问题
minvalue 1  
maxvalue 99999999999  
cycle   
nocache;  

得到序列的语句

select * from user_sequences where sequence_name = upper(‘mysequence‘);  -- sequence_name的值必须是大写的,哪怕创建的时候是小写的

删除序列

drop sequence mysequence;

获取序列的当前值,不递增

select mysequence.currval from dual;  -- 注currval的值是由nextval定义的,即至少执行一次nextval才能执行currval的值

获取序列的当前值,递增,即把当前序列+increment后输出

select mysequence.nextval from dual;

修改序列的值

  • 1.删除原来的序列,重新创建序列,通过修改start with的值
  • 2.通过修改increment的值,修改当前的值,如下,把当前值改为100

      alter sequence mysequence  increment by 98;  -- 修改序列的增加值,这里的98好像不能通过select 100-2 from dual的方式获取,好奇怪
      select mysequence.nextval from dual;
      alter sequence mysequence increment by 1;
  • 3.通过存储过程进行循环,存储过程还有待练习(特别重要)

创建序列语法

 create sequence [序列的名称]
 increment by  [n]   -- n的值可以为正也可以为负,但是不能为0 ,省略该值时,默认为1
 start with [n]    -- 指定生成的第一个序列值,升序时,缺省值为最小值,降序时,缺省值为最大值
 [minvalue n]  |  [nominvalue]  -- 创建序列的最大值 
 [maxvalue n]  |  [nomaxvalue]  -- 设定一个序列的最下值,不能小于初始值
 [cycle] | [nocycle]            --判断是否循环,循环,到达最大值时变为初始值
 [cache n] | [nocache]          --判断是否存在缓存,当需要的序列是连续的时候,一般不设置缓存
 [order desc|asc] | [noorder]  --排序 缺省值为升序

修改序列

 alert sequence [序列的名称] [修改的属性,跟创建序列是一样的]

  1. nominvalue为升序指定最小值为1 ,为降序指定最小值-1026

  2. nomaxvalue 为升序指定最大值1027,为降序指定最大值-1

  3. 使用cache可能会出现数字不连续的原因,数据库把cache n个数组放入内存中,每次使用nextval,从内存中取数字,但是如果突然关机,会从之前内存最大值的下一个开始取,即使没用过的数字也不会被取到

  4. 序列是独立于回滚操作的,即sql执行不成功,但是nextvale的值不会变

  5. 序列只保证获取到的数的唯一的(nocycle的情况下),但是不保证序列的值是连续的,如上面两个原因,都会造成序列不连续

以上是关于oracle序列问题的主要内容,如果未能解决你的问题,请参考以下文章

关于oracle序列的问题

怎么查看oracle创建的序列?

oracle序列怎么用

oracle创建序列的语法

oracle 如何删除新生成的序列号

怎样在oracle中取出当前序列值