Oracle列自增-12c
在ORACLE 12C以前的版本中,如果要实现列自增长,需要通过序列+触发器实现,到了12C ORACLE 引进了Identity Columns新特性,从而实现了列自增长功能。
一、Identity Columns使用语法
GENERATED [ ALWAYS | BY DEFAULT [ ON NULL ] ] AS IDENTITY [ ( identity_options ) ]identity_options
二、identity_clause

2.1 ALWAYS选项
DROP TABLE IDENTITY_TEST_TAB PURGE; CREATE TABLE identity_test_tab ( id NUMBER GENERATED ALWAYS AS IDENTITY, description VARCHAR2(30) );
插入测试1:
INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION')
[SQL]INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION')
受影响的行: 1
时间: 0.008s
插入测试2:
INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION')
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION')
[Err] ORA-32795: cannot insert into a generated always identity column 无法插入到“始终生成”身份列
插入测试3:
INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION')
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION')
[Err] ORA-32795: cannot insert into a generated always identity column

更新测试:
UPDATE IDENTITY_TEST_TAB SET ID=2 WHERE ID=1
[SQL]UPDATE IDENTITY_TEST_TAB SET ID=2 WHERE ID=1
[Err] ORA-32796: cannot update a generated always identity column
结论:
- GENERATED ALWAYS AS IDENTITY 可以不指定该列进行插入
- GENERATED ALWAYS AS IDENTITY不能在该列中插入NULL值
- GENERATED ALWAYS AS IDENTITY不能指定具体值插入
- GENERATED ALWAYS AS IDENTITY 不能使用update更新该列
2.2 BY DEFAULT选项
DROP TABLE identity_test_tab PURGE; CREATE TABLE identity_test_tab ( id NUMBER GENERATED BY DEFAULT AS IDENTITY, description VARCHAR2(30) );
插入测试1:
INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION')
受影响的行: 1
时间: 0.001s
SELECT * FROM identity_test_tab;

插入测试2:
INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION');
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION')
受影响的行: 1
时间: 0.001s
SELECT * FROM identity_test_tab;

插入测试3:
INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION')
[Err] ORA-01400: cannot insert NULL into ("TEST_USER"."IDENTITY_TEST_TAB"."ID")

更新测试:
UPDATE IDENTITY_TEST_TAB SET ID=2 WHERE ID=1
[SQL]UPDATE IDENTITY_TEST_TAB SET ID=2 WHERE ID=1
受影响的行: 1
时间: 0.001sUPDATE IDENTITY_TEST_TAB SET ID=2 WHERE ID=1
结论:
- GENERATED BY DEFAULT AS IDENTITY 可以不指定该列进行插入
- GENERATED BY DEFAULT AS IDENTITY 可以指定具体值插入
- GENERATED BY DEFAULT AS IDENTITY 不能在该列中插入null值
- 可以使用update更新该列,但不能更新为NULL
2.3 DEFAULT ON NULL选项
DROP TABLE identity_test_tab PURGE; CREATE TABLE identity_test_tab ( id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY, description VARCHAR2(30) );
插入测试:
INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');
INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION');
INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');
[SQL]INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION')
受影响的行: 1
时间: 0.003s
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION')
受影响的行: 1
时间: 0.001s
[SQL]INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION')
受影响的行: 1
时间: 0.002s
SELECT * FROM identity_test_tab;

更新测试
UPDATE IDENTITY_TEST_TAB SET ID=3 WHERE ID=1
[SQL]UPDATE IDENTITY_TEST_TAB SET ID=3 WHERE ID=1
受影响的行: 1
时间: 0.004s
结论:
- GENERATED BY DEFAULT ON NULL AS IDENTITY 可以不指定该列进行插入
- GENERATED BY DEFAULT ON NULL AS IDENTITY 方式可以指定具体值插入
- GENERATED BY DEFAULT ON NULL AS IDENTITY 可以在该列中插入null值
- 可以使用update更新该列
三、原理
3.1 Identity Columns 是基于序列实现的
使用此语法实现ID自增,要求必须有创建序列的权限。可以推测是基于序列实现的
执行完建表语句后:
CREATE TABLE identity_test_tab ( id NUMBER GENERATED ALWAYS AS IDENTITY, description VARCHAR2(30) );
查看user_objects
SELECT object_name, object_type FROM user_objects;

发现建表的时候自动生成了一个sequence
SELECT table_name, column_name, generation_type, identity_options FROM all_tab_identity_cols WHERE owner = 'TEST_USER';

表和sequence的关系存在SYS.IDNSEQ$表中
Sys登陆查看
SELECT a.name AS table_name, b.name AS sequence_name FROM sys.idnseq$ c JOIN obj$ a ON c.obj# = a.obj# JOIN obj$ b ON c.seqobj# = b.obj# where a.name='IDENTITY_TEST_TAB';

3.2 GENERATED IDENTITY 中sequence不能单独被删除
DROP TABLE IDENTITY_TEST_TAB
删除表后,该sequence还存在。且该sequence无法被删除

必须
purge table IDENTITY_TEST_TAB,
结论:
- Identity Columns 是基于序列实现的
- GENERATED IDENTITY 中sequence不能单独被删除
- GENERATED IDENTITY 中的表删除,如果存在回收站中,该sequence依然存储,如果表被彻底删除,则sequence也被删除
3.3 执行插入语句时的解释计划
INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');

对比发现:该方式的效率比触发器+序列的方式高!
四、identity_options

查看表的DDL
select dbms_metadata.get_ddl('TABLE','IDENTITY_TEST_TAB') FROM DUAL;
CREATE TABLE "TEST_USER"."IDENTITY_TEST_TAB"
( "ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOT NULL ENABLE,
"DESCRIPTION" VARCHAR2(30)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
INCREMENT BY
用于定义序列的步长,如果省略,则默认为1,如果出现负值,则代表序列的值是按照此步长递减的。
START WITH
定义Oracle序列的初始值(即产生的第一个值),默认为1。
MAXVALUE
定义序列生成器能产生的最大值。选项NOMAXVALUE是默认选项,代表没有最大值定义,这时对于递增序列,系统能够产生的最大值是10的27次方;对于递减序列,最大值是-1。
MINVALUE
定义序列生成器能产生的最小值。选项NOMAXVALUE是默认选项,代表没有最小值定义,
CYCLE和NOCYCLE
表示当序列生成器的值达到限制值后是否循环。CYCLE代表循环,NOCYCLE代表不循环。如果循环,则当递增序列达到最大值时,循环到最小值;对于递减序列达到最小值时,循环到最大值。如果不循环,达到限制值后,继续产生新值就会发生错误。
CACHE
(缓冲)定义存放序列的内存块的大小,默认为20。NOCACHE表示不对序列进行内存缓冲。对序列进行内存缓冲,可以改善序列的性能。
原文地址:https://www.cnblogs.com/xqzt/p/4455149.html
Oracle列自增-12c的更多相关文章
- Oracle列自增实现(2)-Identity Columns in Oracle Database 12c Release 1 (12.1)
Oracle列自增-Identity Columns in Oracle Database 12c Release 1 (12.1) 在ORACLE 12C以前的版本中,如果要实现列自增长,需要通过序 ...
- oracle列自增实现(1)-Sequence+Trigger实现Oracle列自增
Sequence+Trigger实现Oracle列自增 序列的语法格式为: CREATE SEQUENCE 序列名 [INCREMENT BY n] [START WITH n] [{MAXVALUE ...
- Oracle列自增实现(3)-DEFAULT Values Using Sequences
Oracle 12c中,可以使用序列的NEXTVAL and CURRVAL的值作为默认值,来实现列自增! 一.使用序列的NEXTVAL and CURRVAL的值作为默认值 创建序列 CREATE ...
- Oracle ID 自增
实现Oracle Id自增 1.方法一(Oracle Version Oracle 12c版本支持) create table app_student( id integer generated by ...
- oracle官方文档12c对应关系
ADDCI Oracle® Database Data Cartridge Developer's Guide 12c Release 1 (12.1) E15882-05 ADFNS Oracle® ...
- mysql里表以及列的增删改查
在一个表里插入数据(增) insert into 表名 (需要插入的列名如 id,name,age)values (1,'张三',20), (2,'李四',30): 查询表内容(查 ...
- Oracle列操作(增加列,修改列,删除列)
Oracle列操作 增加一列: alter table emp4 add test varchar2(10); 修改一列: alter table emp4 modify test varchar2( ...
- Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍
引用自 :http://www.2cto.com/database/201307/224836.html Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍 先假设有这么一个表 ...
- oracle列合并
在很多场合,我们会须要用到oracle列合并,oracle提供了一些方法用于把某列的多行数据合并成一行. 一.10G曾经使用WMSYS.WM_CONCAT wmsys.wm_concat将字段的值 ...
随机推荐
- Queue 队列的使用
队列一个先进先出的对象集合 public class PlayChickTopicData : MonoBehaviour { Queue<TopicData> topicDatas = ...
- 如何查看jar包的版本号?(转)
转自 : http://www.cnblogs.com/wych/p/4072913.html jar包根目录里的META-INF目录下的MANIFEST.MF文件里一般有会记录版本信息,可以到这个文 ...
- useful urls
数据挖掘技术: http://ddl.escience.cn/f/IwoF?rid=8188575 李航 统计学习方法: http://ddl.escience.cn/f/Iwn0
- informix 随笔
1.新建连接create new database connection 2.database Url: jdbc:informix-sqli://119.84.39.35:29999/gps_pr ...
- hibernate二级缓存整合
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http:// ...
- js获取世界不同时区的当前时间
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- sql注入-推断是否存在SQL注入-加法和减法
这里我们需要区分一下数字型和字符串型: 数字型:不需要使用单引号来表示 其他类型:使用单引号来表示 综合上述,我们可以发现我们的例子是数字型的,这样我们就可以使用加法和减法来判断了. 加法,我们在参数 ...
- 创建一个dynamics 365 CRM online plugin (五) - Images in Plugin
Snapshots of the primary entity's attributes from database before(pre) and after (post) the core pla ...
- TypeScript 学习资料
TypeScript 学习资料: 学习资料 网址 TypeScript Handbook(中文版)(推荐) https://m.runoob.com/manual/gitbook/TypeScript ...
- TZipFile FileNames中文乱码解决办法
TEncoding.Default.GetString(zip.FileInfo[0].FileName); 补充说明: Zip.Extract(Zip.FileName[0], 'd:\'); 解压 ...