Oracle新表使用序列(sequence)做为插入值,初始值不是第一个,oraclesequence数据库
使用oracle11g插入数据时遇到这样一个问题:oracle
1 --建立测试表--
2 CREATE TABLE tbl_test(
3 test_id NUMBER PRIMARY KEY,
4 test_name VARCHAR2(20)
5 );
6
7 --为tbl_test建立序列--
8 CREATE SEQUENCE seq_test
9 INCREMENT BY 1 -- 每次加几个
10 START WITH 1 -- 从1开始计数
11 ;
12
13 --插入测试数据--
14 INSERT INTO tbl_test VALUES(seq_test.nextval,'测试');
15 COMMIT;
16
17 --查询表中的数据
18 SELECT * FROM tbl_test;学习
显示结果:测试
问题缘由:排序
·当咱们使用序列做为插入数据时,若是使用了“延迟段”技术,则跳过序列的第一个值事务
·Oracle从 11.2.0.1版本开始,提供了一个“延迟段建立”特性:
即内存
当咱们建立了新的表(table)和序列(sequence),
在插入(insert)语句时,序列会跳过第一个值(1)。
因此结果是插入的序列值从 2(序列的第二个值) 开始, 而不是 1开始。rem
想要解决这个问题有两种方法:
更改数据库的“延迟段建立”特性为false(须要有相应的权限)
ALTER SYSTEM SET deferred_segment_creation=FALSE;
或者
在建立表时让seqment当即执行,如:io
CREATE TABLE tbl_test(
test_id NUMBER PRIMARY KEY,
test_name VARCHAR2(20)
)
SEGMENT CREATION IMMEDIATE;table
以上两种方法均可以解决以前的问题。
oracle中怎得到某个表的正在或曾经使用的sequence?
好象它们二者没有依属联系,而确实在工做中又容易碰见此类问题.
从序列的角度来思考的话,仅跟用户相关。
如下步骤能够参考:
1 从系统视图中取得全部序列的相关信息。
注意相关权限。
select sequence_name,min_value,max_value,increment_by,last_number from all_sequences
若是可以可以排除 用户A的表数据,采用了用户B的sequence来生成数据的状况,那能够加上
where sequence_owner=' '; -----适合的用户
或者从USER_SEQUENCES中提取。
2 从关心的表中提取敏感字段的最大值
select max(id) from test;
3 将二者对比。或者将上述两个查询链接到一块儿来查询。若是当前该表没有被插入,而且,近期没有被删除,那么,该max(id)+1=last_number ;
若是非要弄清楚的话,那就将表数据保护起来,拒绝删除数据,当发现数据插入后,观察插入的频度和事务提交后序列列值变化的大小,由此最终能判断出是哪一个序列号。基于非要准确的搞清楚的前提下,使用排出法,将上述最接近的序列按照从轻度怀疑到高度怀疑的顺序,再备份的状况下,依次删除、恢复.....这样确定能搞准。
还有一个最好的办法之后遇到这种状况就简单了。在该表上创建基于插入后的触发器,在触发器中包含上面查询思想,将max(id)+1=last_number 的序列名返回。。。。则绝对不会错
.
知识有限,在此也期盼能学习到更高级的方法。
但愿能帮到你。.
oracle表中怎建序列
在oracle中sequence就是所谓的序列号,每次取的时候它会自动增长,通常用在须要按序列号排序的地方。
一、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的地方:
能够看以下例子:
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防止这种状况。
二、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 ;