详解ORACLE SEQUENCE用法
在Oracle数据库开发中,SEQUENCE(序列)是用于生成唯一数值的数据库对象,常被用来生成主键值、业务流水号等需要唯一标识的场景。它可以在多用户环境下保证生成数值的唯一性,且不需要额外的锁机制,性能较高。本文将详细介绍Oracle SEQUENCE的创建、使用、修改、删除等核心操作。
一、SEQUENCE基本概念
SEQUENCE是Oracle数据库提供的用于生成连续整数值的对象,它的生成过程独立于事务,不会因为事务回滚而撤销已经生成的数值。需要注意的是,SEQUENCE生成的数值并不一定完全连续,当发生实例异常关闭、多用户并发获取等情况时,可能会出现跳号现象。
二、创建SEQUENCE
创建SEQUENCE需要使用CREATE SEQUENCE语句,语法如下:
CREATE SEQUENCE sequence_name [INCREMENT BY n] -- 每次增长的步长,默认值为1,可以是正整数或负整数 [START WITH n] -- 起始值,默认值为1 [MAXVALUE n | NOMAXVALUE] -- 最大值,默认NOMAXVALUE,即10^27-1 [MINVALUE n | NOMINVALUE] -- 最小值,默认NOMINVALUE,即1 [CYCLE | NOCYCLE] -- 达到极值后是否循环,默认NOCYCLE [CACHE n | NOCACHE] -- 缓存的序列值数量,默认CACHE 20,NOCACHE不缓存 [ORDER | NOORDER]; -- 是否保证顺序生成,默认NOORDER
以下是一个创建SEQUENCE的示例,创建一个名为user_id_seq的序列,从100开始,每次增长1,最大值999999,不循环,缓存20个值:
CREATE SEQUENCE user_id_seq INCREMENT BY 1 START WITH 100 MAXVALUE 999999 NOCYCLE CACHE 20;
三、使用SEQUENCE
SEQUENCE生成的值可以通过两个伪列获取:NEXTVAL和CURRVAL。
NEXTVAL:返回序列的下一个值,每次调用都会让序列前进到下一个数值。CURRVAL:返回序列的当前值,调用前必须先调用一次NEXTVAL初始化序列,否则会报错。
3.1 查询序列值
可以直接通过SELECT语句查询序列的下一个值和当前值:
-- 获取下一个序列值 SELECT user_id_seq.NEXTVAL FROM DUAL; -- 获取当前序列值(需要先调用过NEXTVAL) SELECT user_id_seq.CURRVAL FROM DUAL;
3.2 在INSERT语句中使用
SEQUENCE最常用的场景是在插入数据时生成主键值,示例如下:
-- 假设存在user_info表,结构为:id NUMBER PRIMARY KEY, user_name VARCHAR2(50) INSERT INTO user_info (id, user_name) VALUES (user_id_seq.NEXTVAL, '张三'); COMMIT;
3.3 在UPDATE语句中使用
也可以在更新数据时利用序列生成新的值:
UPDATE user_info SET id = user_id_seq.NEXTVAL WHERE user_name = '李四'; COMMIT;
四、查看SEQUENCE信息
可以通过数据字典视图查看当前用户下的所有SEQUENCE信息,常用的视图有USER_SEQUENCES:
SELECT sequence_name, min_value, max_value, increment_by, last_number FROM USER_SEQUENCES;
其中last_number表示序列最后一次缓存的最大值,如果使用了CACHE,该值会比实际已使用的最大值大。
五、修改SEQUENCE
如果需要调整序列的配置,可以使用ALTER SEQUENCE语句,语法和创建时类似,但部分参数有使用限制:
ALTER SEQUENCE sequence_name [INCREMENT BY n] [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE] [CYCLE | NOCYCLE] [CACHE n | NOCACHE] [ORDER | NOORDER];
需要注意的限制:
不能修改序列的起始值(START WITH),如果需要修改起始值,只能删除序列后重新创建。
修改后的新值会立即生效,不会影响已经生成的历史数值。
示例:将user_id_seq的最大值修改为1999999,缓存值修改为50:
ALTER SEQUENCE user_id_seq MAXVALUE 1999999 CACHE 50;
六、删除SEQUENCE
如果不再需要某个序列,可以使用DROP SEQUENCE语句删除:
DROP SEQUENCE user_id_seq;
删除序列后,所有依赖该序列的对象(如使用了序列的触发器、存储过程)都会失效,需要重新编译或调整。
七、使用注意事项
SEQUENCE生成的值不保证连续,当数据库实例异常关闭、序列缓存被清空、多用户并发获取时,都可能出现跳号。
不要在WHERE条件中使用
NEXTVAL,因为每次判断都会让序列前进,可能导致意外的数值消耗。如果业务需要严格连续的数值,不建议使用SEQUENCE,可以考虑通过程序加锁或者数据库表的计数器方式实现。
访问示例网站(https://www.ipipp.com)可以查看Oracle官方文档中关于SEQUENCE的更多详细说明。