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 [序列的名称] [修改的属性,跟创建序列是一样的]
注
nominvalue为升序指定最小值为1 ,为降序指定最小值-1026
nomaxvalue 为升序指定最大值1027,为降序指定最大值-1
使用cache可能会出现数字不连续的原因,数据库把cache n个数组放入内存中,每次使用nextval,从内存中取数字,但是如果突然关机,会从之前内存最大值的下一个开始取,即使没用过的数字也不会被取到
序列是独立于回滚操作的,即sql执行不成功,但是nextvale的值不会变
序列只保证获取到的数的唯一的(nocycle的情况下),但是不保证序列的值是连续的,如上面两个原因,都会造成序列不连续
以上是关于oracle序列问题的主要内容,如果未能解决你的问题,请参考以下文章