oracle实现插入数据时主键自增

本文详细介绍如何在Oracle数据库中使用PL/SQL创建学生信息表,并通过自增序列和触发器实现自动ID分配,最后演示了一个批量插入数据的示例代码。

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

在看ORACLE_PL/SQL实例精解的时候用到了student表,需要自己创建。

1  首先是建表语句

create table student (
       student_id number(8) not null primary key, --主键列
       first_name varchar2(50), -- 名字
       last_name varchar2(50)   -- 姓
);

2 创建自增序列

create sequence seq_student
       minvalue 1  --最小值
       nomaxvalue --最大值
       start with 1 --起始值
       increment by 1  --增长基数
       nocycle  --不循环,一直增加
       nocache ; -- 不使用缓存

到这里其实就可以使用了,只是在插入的时候必须要自己调用,像这样

insert into student(student_id,first_name,last_name) values(seq_student.nextval,'','');

为了可以不关注主键列,创建一个触发器。


3 创建触发器(插入数据时触发)

create trigger tri_student_ins 
       before insert on student for each row  when (new.student_id is null)
    begin 
      select seq_student.nextval into:new.student_id from dual;
    end;  

这样就可以插入数据了

insert into student(first_name,last_name) values('','');

4 写一个pl/sql代码块,批量插入数据

declare 
       i number := 1;
       v_first_name varchar2(50);
       v_last_name varchar2(50);
begin 
  for i in 1 .. 200 
    loop 
      v_first_name := '' || to_char(i);
      v_last_name := '' || to_char(i);
      insert into student(first_name,last_name) values(v_first_name,v_last_name);
      commit;
    end loop;
end;   

 

<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建表并指定主键
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值