向oralce表中添加数据时如何让主键自增

本文介绍如何在PL/SQL中使用序列和触发器实现表的自增ID功能,适用于不想手动设置ID的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近来项目中需要向某个表插入数据,但是id只做主键并不显示在页面中,故想要把主键设成在插入其他数据时自动增长。PL/SQL中没有找到像MySql中一样的自增按钮选项,从网上搜了搜大家都是用自增序列和触发器来实现这个要求的,下面来整理一下。

1.表中id是主键,非空但是从页面添加数据时并不会让用户输入。表明atm_register

2.创建一个序列,比如,SEQ_ATM_SFXH
create sequence SEQ_ATM_SFXH
minvalue 0
maxvalue 99999999
start with 0
increment by 1
cycle;
每次查询的时候返回

3.创建一个触发器

create or replace trigger SAVEATMREGISTER
before insert on atm_register   --在向atm_register插入数据时触发
for each row
begin
    select SEQ_ATM_ID.nextval into:new.id from dual;  --调用序列
end SAVEATMREGISTER;

这样在向表中插入数据时id就会自动增长啦~





欢迎各位程序猿&程序媛批评指正~

<think>我们已知在Oracle中实现自主键需要两个步骤:创建序列(SEQUENCE)和创建触发器(TRIGGER)。以下是创建指定主键并设置自的详细步骤: ### 步骤1:创建并指定主键 在创建的语句中,为主键字段指定`PRIMARY KEY`约束。 ### 步骤2:创建序列 序列用于生成自数字,可以设置起始值、步长等。 ### 步骤3:创建触发器 在插入数据前,触发器自动从序列中获取下一个值并赋给主键字段。 ### 完整示例 假设我们要创建一个名为`employees`的主键为`id`,并实现自。 #### 1. 创建 ```sql CREATE TABLE employees ( id NUMBER(10) PRIMARY KEY, -- 指定主键 name VARCHAR2(50) NOT NULL, department VARCHAR2(50) ); ``` #### 2. 创建序列 ```sql CREATE SEQUENCE employees_seq INCREMENT BY 1 -- 每次增加1 START WITH 1 -- 从1开始 NOMAXVALUE -- 无最大值限制(或指定最大值:MAXVALUE 9999) NOCYCLE -- 不循环 CACHE 20; -- 缓存20个序列值(可选,根据性能调整) ``` #### 3. 创建触发器 ```sql CREATE OR REPLACE TRIGGER employees_trigger BEFORE INSERT ON employees FOR EACH ROW BEGIN -- 当插入数据,如果主键字段为或0,则从序列中获取新值 IF :new.id IS NULL OR :new.id = 0 THEN SELECT employees_seq.NEXTVAL INTO :new.id FROM dual; END IF; END; / ``` ### 验证自主键 插入数据不指定`id`: ```sql INSERT INTO employees (name, department) VALUES ('张三', '技术部'); INSERT INTO employees (name, department) VALUES ('李四', '市场部'); ``` 查询数据: ```sql SELECT * FROM employees; ``` 结果应显示自动生成的`id`(从1开始递)。 ### 注意事项 1. **触发器条件** `IF :new.id IS NULL OR :new.id = 0` 确保只有主键或0才触发自。如果插入指定了非非0的`id`,则使用指定值(需确保不重复)。 2. **序列缓存** `CACHE`选项可提升性能,但若数据库意外关闭可能导致序列号不连续(不影响唯一性)。 3. **主键冲突** 如果手动插入重复的`id`,会违反主键约束导致错误。 4. **修改自起始值** 调整序列的`START WITH`值即可: ```sql DROP SEQUENCE employees_seq; CREATE SEQUENCE employees_seq START WITH 1000; -- 从1000开始 ``` ### 相关问题 1. 如何重置Oracle序列的起始值? 2. Oracle中如何查看当前序列的值? 3. 插入数据跳过触发器的方法有哪些? 4. 如何修改现有主键为自? [^1]: Oracle创建并实现主键 [^2]: Oracle设置主键 [^3]: Oracle 创建并设置主键 [^4]: Oracle数据库建并设置主键 [^5]: Oracle并指定主键</think>在 Oracle 数据库中创建设置主键并实现自功能,需要通过三个步骤完成:创建定义主键 → 创建序列 → 创建触发器。以下是详细操作指南: --- ### 完整操作步骤 #### 1. 创建并指定主键字段 ```sql CREATE TABLE employees ( id NUMBER(10) PRIMARY KEY, -- 指定主键 name VARCHAR2(50) NOT NULL, department VARCHAR2(50) ); ``` - **关键点**: - `id` 字段定义为 `PRIMARY KEY`(隐含 `NOT NULL` 和 `UNIQUE` 约束) - 主键字段类型建议为 `NUMBER`,便于序列赋值[^5] #### 2. 创建序列(Sequence) ```sql CREATE SEQUENCE employees_seq INCREMENT BY 1 -- 每次增加1 START WITH 1 -- 从1开始计数 NOMAXVALUE -- 无最大值限制(或使用 MAXVALUE 9999) NOCYCLE -- 不循环 NOCACHE; -- 无缓存(保证连续性) ``` - **参数说明**: - `INCREMENT BY`:自步长 - `START WITH`:起始值 - `NOCACHE`:避免序列号断层(重要!) #### 3. 创建触发器(Trigger)实现自 ```sql CREATE OR REPLACE TRIGGER employees_trg BEFORE INSERT ON employees FOR EACH ROW BEGIN -- 当主键或0触发自 IF :new.id IS NULL OR :new.id = 0 THEN SELECT employees_seq.NEXTVAL INTO :new.id FROM dual; END IF; END; / ``` - **触发器逻辑**: - `BEFORE INSERT`:在插入数据前触发 - `IF :new.id IS NULL`:仅当未提供主键触发 - `SELECT ... INTO :new.id`:将序列值赋给主键[^2][^4] --- ### 验证自效果 ```sql -- 插入数据(不指定id) INSERT INTO employees (name, department) VALUES ('张三', '技术部'); -- 查询结果 SELECT * FROM employees; ``` **输出结果**: ``` ID | NAME | DEPARTMENT ----|------|----------- 1 | 张三 | 技术部 ``` --- ### 关键注意事项 1. **序列缓存问题** 使用 `NOCACHE` 保证主键连续性,但会影响性能。高并发场景可改用 `CACHE 20`(需容忍可能的断层)[^1] 2. **主键手动赋值** 如果插入显式指定了 `id` 值(如 `INSERT INTO employees(id, ...)`),触发器不会覆盖该值 3. **修改现有** 对已有添加主键: ```sql ALTER TABLE existing_table ADD (id NUMBER(10) PRIMARY KEY); CREATE SEQUENCE existing_seq ...; CREATE TRIGGER existing_trg ...; ``` 4. **性能优化** 当数据量较大,在序列创建后执行: ```sql ALTER TABLE employees MODIFY id DEFAULT ON NULL employees_seq.NEXTVAL; ``` 可减少触发器调用次数[^3] --- ### 常见问题解决 **Q:插入报错 "ORA-00001: 违反唯一约束条件"** **原因**:手动插入的ID与序列生成值冲突 **方案**:检查序列当前值并重置: ```sql SELECT employees_seq.CURRVAL FROM dual; ALTER SEQUENCE employees_seq INCREMENT BY 100; -- 跳过冲突值 SELECT employees_seq.NEXTVAL FROM dual; -- 应用跳转 ALTER SEQUENCE employees_seq INCREMENT BY 1; -- 恢复步长 ``` **Q:如何查看已创建的自主键?** ```sql -- 查看序列 SELECT sequence_name FROM user_sequences; -- 查看触发器 SELECT trigger_name FROM user_triggers; ``` --- ### 相关问题 1. 如何修改Oracle序列的起始值? 2. 高并发场景下如何避免序列竞争? 3. Oracle主键与MySQL的AUTO_INCREMENT有何区别? 4. 如何为现有添加主键? [^1]: Oracle创建并实现主键 [^2]: Oracle设置主键 [^3]: Oracle创建并设置主键 [^4]: Oracle数据库建并设置主键 [^5]: Oracle并指定主键
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值