Oracle数据库本身没有像MySQL那样直接支持自增字段的原生语法,需要通过特定的技术方案来实现字段自增的效果,目前主流的实现方式有两种,分别是序列配合触发器的传统方案,以及Oracle 12c及更高版本支持的身份列方案。

方法一:使用sequence和触发器实现自增列
这是Oracle 12c之前最常用的自增列实现方式,核心思路是先创建一个序列用来生成递增的数值,再通过触发器在插入数据时自动将序列的下一个值赋值给目标字段。
1. 创建测试表
首先创建一个需要自增列的测试表,这里以用户表为例,id字段作为自增主键:
-- 创建用户表,id为主键
CREATE TABLE user_info (
id NUMBER(10) PRIMARY KEY,
user_name VARCHAR2(50) NOT NULL,
create_time DATE DEFAULT SYSDATE
);
2. 创建序列
序列是Oracle中用来生成唯一递增或递减数值的数据库对象,我们创建一个从1开始、每次递增1的序列:
-- 创建自增序列,起始值为1,步长为1,不缓存,不循环 CREATE SEQUENCE user_id_seq START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
这里参数说明:START WITH指定序列起始值,INCREMENT BY指定每次递增的步长,NOCACHE表示不预先缓存序列值避免跳号,NOCYCLE表示序列值不会循环复用。
3. 创建触发器
触发器的作用是在向表中插入数据时,自动将序列的下一个值赋值给id字段,不需要手动在插入语句中指定id值:
-- 创建触发器,在插入数据前自动给id字段赋值
CREATE OR REPLACE TRIGGER user_id_trigger
BEFORE INSERT ON user_info
FOR EACH ROW
BEGIN
-- 当插入的id为空时,使用序列的下一个值赋值
IF :NEW.id IS NULL THEN
SELECT user_id_seq.NEXTVAL INTO :NEW.id FROM DUAL;
END IF;
END;
/
4. 测试自增效果
插入数据时不指定id字段,查看是否自动生成自增值:
-- 插入测试数据,不指定id
INSERT INTO user_info (user_name) VALUES ('张三');
INSERT INTO user_info (user_name) VALUES ('李四');
INSERT INTO user_info (user_name) VALUES ('王五');
-- 提交事务
COMMIT;
-- 查询表数据,查看id是否自增
SELECT * FROM user_info;
执行后可以看到id字段会自动按照1、2、3的顺序递增生成。
方法二:使用identity column实现自增列
Oracle 12c版本引入了身份列(identity column)特性,支持类似MySQL的自增字段语法,不需要手动创建序列和触发器,使用起来更加简便。
1. 创建带身份列的表
在创建表的时候,直接给字段指定GENERATED AS IDENTITY属性即可:
-- 创建带身份列的表,id自动自增
CREATE TABLE user_info_new (
id NUMBER(10) GENERATED AS IDENTITY PRIMARY KEY,
user_name VARCHAR2(50) NOT NULL,
create_time DATE DEFAULT SYSDATE
);
身份列还支持自定义起始值和步长,比如需要起始值为100,步长为2,可以写成:
-- 自定义起始值和步长的身份列
CREATE TABLE user_info_custom (
id NUMBER(10) GENERATED ALWAYS AS IDENTITY (START WITH 100 INCREMENT BY 2) PRIMARY KEY,
user_name VARCHAR2(50) NOT NULL
);
这里GENERATED ALWAYS表示插入数据时不能手动指定id值,只能由数据库自动生成;如果需要允许手动指定id值,可以改成GENERATED BY DEFAULT。
2. 测试身份列自增效果
插入数据时不指定id字段,查看自增效果:
-- 插入测试数据
INSERT INTO user_info_new (user_name) VALUES ('赵六');
INSERT INTO user_info_new (user_name) VALUES ('孙七');
-- 提交事务
COMMIT;
-- 查询数据
SELECT * FROM user_info_new;
执行后可以看到id字段会自动按照1、2的顺序递增生成,和预期效果一致。
两种方法的对比和选择
我们可以通过下面的表格对比两种自增列实现方案的特点,方便根据实际场景选择:
| 对比项 | sequence+触发器方案 | identity column方案 |
|---|---|---|
| 适用Oracle版本 | 所有Oracle版本 | Oracle 12c及以上版本 |
| 实现复杂度 | 需要创建序列、触发器,步骤较多 | 建表时直接指定属性,步骤简单 |
| 维护成本 | 需要单独维护序列和触发器对象 | 数据库自动维护,无需额外操作 |
| 灵活性 | 可以自定义序列的更多属性,适配复杂场景 | 属性配置相对固定,满足基础自增需求 |
如果使用的是Oracle 12c及以上版本,优先选择身份列方案,实现简单维护方便;如果是旧版本Oracle,或者需要更复杂的序列控制逻辑,可以选择序列配合触发器的方案。
注意事项
- 使用序列配合触发器方案时,如果手动给id字段插入了值,触发器不会覆盖该值,只有当id为空时才会自动赋值。
- 身份列如果使用
GENERATED ALWAYS模式,插入数据时手动指定id会报错,需要根据需求选择合适的生成模式。 - 序列的缓存设置如果开启,数据库异常重启可能会导致序列值跳号,对自增连续性要求高的场景建议设置
NOCACHE。 - 不管是哪种方案,自增列都建议配合主键约束使用,避免生成重复值影响数据唯一性。
Oracle自增列sequence触发器identity_column修改时间:2026-07-04 16:54:33