Oracle在创建表时和其他的数据库有点不一样,MySQL中可以使用“auto_increment”即可。但是oracle12c以前有点麻烦,需要使用序列和触发器达到目的。从12c开始,可以使用新特性Identity Columns实现自增长列功能,也可以使用序列的NEXTVAL and CURRVAL的值作为列的默认值,来实现列自增。
1、11g序列加触发器为表增加自增字段
--表增加列
alter table DW_SUNACPARK_EQUI_FAULT_MANU add auto_increment_no number(12) ;-- Add comments to the columns comment on column DW_SUNACPARK_EQUI_FAULT_MANU.auto_increment_no is '触发器自增ID';
--更改列值
Update DW_SUNACPARK_EQUI_FAULT_MANU set auto_increment_no=rownum;commit;select max(auto_increment_no) from DW_SUNACPARK_EQUI_FAULT_MANU;alter table DW_SUNACPARK_EQUI_FAULT_MANU modify auto_increment_no not null ;
--创建序列 start根据上边表中数据最大值
create sequence SEQ_DW_SPARK_EQUI_FAULT_MANUminvalue 1nomaxvaluestart with 29increment by 1cache 20;
--建立触发器
CREATE OR REPLACE TRIGGER TRI_DW_SPARK_EQUI_FAULT_MANU BEFORE INSERT ON DW_SUNACPARK_EQUI_FAULT_MANU FOR EACH ROW WHEN (new.auto_increment_no is null)DECLARE v_no DW_SUNACPARK_EQUI_FAULT_MANU.auto_increment_no%TYPE;BEGIN SELECT SEQ_DW_SPARK_EQUI_FAULT_MANU.nextval INTO v_no FROM DUAL; :new.auto_increment_no := v_no;END TRI_DW_SPARK_EQUI_FAULT_MANU;
2、12c使用序列的NEXTVAL and CURRVAL的值作为默认值
(1)默认值可为空列
--创建序列
create sequence seq_testminvalue 1nomaxvaluestart with 1increment by 1cache 10;
--建表
CREATE TABLE test ( id NUMBER DEFAULT seq_test.NEXTVAL, name VARCHAR2(20) );
--插入数据
INSERT INTO test (name) VALUES ('only name');INSERT INTO test (id, name) VALUES (666, 'id=666 and name');INSERT INTO test (id, name) VALUES (NULL, 'id=NULL and name');commit;
--查询数据
select * from test;id name------ ------1 only name666 id=666 and name(Null) id=NULL and name
(2)默认值非空列
--创建序列
create sequence seq_nonull_testminvalue 1nomaxvaluestart with 1increment by 1cache 10;
--建表
CREATE TABLE test2 ( id1 NUMBER DEFAULT seq_test.NEXTVAL, id2 NUMBER DEFAULT seq_nonull_test.NEXTVAL,name VARCHAR2(20) );
--插入数据
INSERT INTO test2 (name) VALUES ('only name');INSERT INTO test2 (id1,id2, name) VALUES (666,666, 'id1=666 id2=666 and name');INSERT INTO test2 (id1,id2,name) VALUES (NULL,NULL, 'id1=NULL id2=NULL and name');commit;
--查询数据
select * from test;id1 id2 name------ ------ ------1 1 only name666 666 id1=666 id2=666 and name(Null) 2 id1=NULL id2=NULL and name
查询数据,可以看到id2为NULL时候,被默认转换使用了seq_nonull_test.NEXTVAL。
注:
采用此种方法,一定要注意不要自行插入列值,避免与sequence生成的出现冲突。12c以后,最好使用新特性Identity Columns。
3、12C 新特性Identity Columns


(1)GENERATED ALWAYS AS IDENTITY方式测试
--创建表
create table test3 (id number GENERATED ALWAYS AS IDENTITY,name varchar2(30));
--查询对象
select object_name,object_type from user_objects;OBJECT_NAME OBJECT_TYPE--------------- -----------------------ISEQ$$_15264 SEQUENCETEST3 TABLE
--查询创建表DDL语句
select dbms_metadata.get_ddl('TABLE','TEST3') FROM DUAL;DBMS_METADATA.GET_DDL('TABLE','TEST3')-------------------------------------------------------------------------------- CREATE TABLE "TEST"."TEST3" ( "ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOT NULL ENABLE, "NAME" VARCHAR2(100) ) SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING TABLESPACE "TEST"
--插入、更改、删除数据
INSERT INTO TEST3 VALUES(1,'DBA');INSERT INTO TEST3 VALUES(1,'DBA')*第 1 行出现错误:ORA-32795: 无法插入到“始终生成”身份列INSERT INTO TEST3 (name) VALUES('DBA');已创建 1 行。INSERT INTO TEST3 (name) VALUES('SYSDBA');已创建 1 行。commit;提交完成。select * from test3; ID NAME---------- ------------------------------ 1 DBA 2 SYSDBAupdate test3 set id=3 where id=2;update test3 set id=3 where id=2 *第 1 行出现错误:ORA-32796: 无法更新“始终生成”身份列delete from test3 where id=1;已删除 1 行。commit;提交完成。select ISEQ$$_15264.nextval from dual; NEXTVAL---------- 3INSERT INTO TEST3 (name) VALUES('SYSTEM');已创建 1 行。commit;提交完成。select * from test; ID NAME---------- ------------------------------ 2 SYSDBA 4 SYSTEM
--删除序列
drop sequence ISEQ$$_15264;drop sequence ISEQ$$_15264*第 1 行出现错误:ORA-32794: 无法删除系统生成的序列
--删除表
drop table test3;表已删除。select object_name,object_type from user_objects where object_name=' ISEQ$$_15264';OBJECT_NAME OBJECT_TYPE-------------------- -----------------------ISEQ$$_15264 SEQUENCEpurge table test3;表已清除。select object_name,object_type from user_objects where object_name='ISEQ$$_15264';未选定行
结论:
GENERATED ALWAYS AS IDENTITY 列无法人工指定值和修改该值;
GENERATED IDENTITY 本质也是通过SEQUENCE实现;
GENERATED IDENTITY 中SEQUENCE不能单独被删除;
GENERATED IDENTITY 中的表删除,如果存在回收站中,该SEQUENCE依然存储,如果表被彻底删除,则SEQUENCE也被删除;
GENERATED IDENTITY 中的SEQUENCE可以通过SELECT语句查询;
通过ALTER TABLE语句来修改GENERATED IDENTITY 的SEQUENCE相关值。
(2)GENERATED BY DEFAULT AS IDENTITY方式测试
create table test4 (id number GENERATED BY DEFAULT AS IDENTITY,name varchar2(100)) tablespace test;表已创建。insert into test4 values (1,'DBA');已创建 1 行。insert into test4(name) values ('SYSDBA');已创建 1 行。col name for a20select * from test4; ID NAME---------- -------------------- 1 DBA 1 SYSDBAinsert into test4 values (null,'DBA');insert into test4 values (null,'DBA')*第 1 行出现错误:ORA-01400: 无法将 NULL 插入 ("TEST"."test4"."ID")desc test4名称 是否为空? 类型----------------------------------------- -------- ---------------------------ID NOT NULL NUMBERNAME VARCHAR2(100)
结论:
GENERATED BY DEFAULT AS IDENTITY方式不能在该列中插入null值;
GENERATED BY DEFAULT AS IDENTITY方式可以指定具体值插入。
(3)GENERATED BY DEFAULT ON NULL AS IDENTITY方式测试
create table test5 (id number GENERATED BY DEFAULT on null AS IDENTITY,name varchar2(100)) tablespace test;表已创建。desc test5 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER NAME VARCHAR2(100)insert into test5 values (null,'DBA');已创建 1 行。select * from test5; ID NAME---------- -------------------- 1 DBA
结论:
GENERATED BY DEFAULT ON NULL AS IDENTITY的列上可以查询null值,只是默认转换为对应的sequence值。
4、MySQL自增列
--Mysql 中每张表只能有一个自增列,并且自增列必须是主键或者唯一键。
root@localhost [test]> create table test6(id int not null auto_increment primary key);Query OK, 0 rows affected (0.01 sec)
-插入空值,是允许的,默认会用自增列值插入。
root@localhost [test]>insert into test6 values(); Query OK, 1 row affected (0.01 sec)root@localhost [test]>select * from test6;+----+| id |+----+| 1 |+----+1 row in set (0.00 sec)
--允许插入的值不连续
root@localhost [test]>insert into test6 values(3);Query OK, 1 row affected (0.00 sec)root@localhost [test]>select * from test6;+----+| id |+----+| 1 || 3 |+----+2 rows in set (0.00 sec)
--表加一列,显式插入新增列,自增列会隐式地从当前最大值自增。
root@localhost [test]>alter table test6 add b int;Query OK, 0 rows affected (0.04 sec)Records: 0 Duplicates: 0 Warnings: 0root@localhost [test]>insert into test6(b) values(4);Query OK, 1 row affected (0.00 sec)root@localhost [test]>select * from test6;+----+------+| id | b |+----+------+| 1 | NULL || 3 | NULL || 4 | 4 |+----+------+3 rows in set (0.00 sec)