Oracle中建表并且设置主键自增

本文介绍如何在Oracle数据库中通过创建表、序列和触发器实现ID自增功能,并提供了具体的SQL语句及验证方法。

1.创建user1表

create table user1(
  id number primary key,
  name varchar2(20)not null,
  password varchar2(20) not null,
  age number
);

2.创建序列

 CREATE SEQUENCE USER_ID_SEQ INCREMENT BY 1 START WITH 1;

创建序列从1开始每次自增1

3.创建触发器
CREATE OR REPLACE TRIGGER TRG_USER1 BEFORE INSERT ON USER1 FOR EACH ROW BEGIN SELECT USER_ID_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL; END TRG_USER1;

验证:执行新增语句:
 insert into user1(name,password,age) values('张三','2222',20);
执行成功,id不需要手动写入,实现自增。
PS:
删除触发器:
drop SEQUENCE  USER_ID_SEQ
删除序列:
drop trigger  TRG_USER1



<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、付费专栏及课程。

余额充值