Oracle 12c 新特性 --- 标识列

1概念说明

Table columns have been enhanced to support the American National Standards Institute (ANSI) SQL keyword IDENTITY.
This provides a standards based approach to the declaration of automatically incrementing columns simplifying application development and making the migration of DDL to Oracle simpler.

表列已经增强,以支持美国国家标准协会(ANSI)SQL关键字标识。
这提供了一种基于标准的方法,以自动递增的列来简化应用程序开发,并使DDL迁移到Oracle更简单。

Oracle Database 12c Release 1 implements ANSI-compliant IDENTITY columns. Migration from database systems that use identity columns is simplified and can take advantage of this new functionality.

This feature implements auto increment by enhancing DEFAULT or DEFAULT ON NULL semantics for use by SEQUENCE.NEXTVAL and SYS_GUID, supports built-in functions and implicit return of default values.

创建语法:
GENERATED
[ ALWAYS | BY DEFAULT [ ON NULL ] ]
AS IDENTITY [ ( identity_options ) ]

identity_clause

Use this clause to specify an identity column. The identity column will be assigned an increasing or decreasing integer value from a sequence generator for each subsequent INSERT statement. You can use the identity_options clause to configure the sequence generator.

ALWAYS 
If you specify ALWAYS, then Oracle Database always uses the sequence generator to assign a value to the column. If you attempt to explicitly assign a value to the column using INSERT or UPDATE, then an error will be returned. This is the default.

BY DEFAULT 
If you specify BY DEFAULT, then Oracle Database uses the sequence generator to assign a value to the column by default, but you can also explicitly assign a specified value to the column. If you specify ON NULL, then Oracle Database uses the sequence generator to assign a value to the column when a subsequent INSERT statement attempts to assign a value that evaluates to NULL.

identity_options

Use the identity_options clause to configure the sequence generator. The identity_options clause has the same parameters as the CREATE SEQUENCE statement. Refer to CREATE SEQUENCE for a full description of these parameters and characteristics. The exception is START WITH LIMIT VALUE, which is specific to identity_options and can only be used with ALTER TABLE MODIFY. Refer to identity_options for more information.

Note:
When you create an identity column, Oracle recommends that you specify the CACHE clause with a value higher than the default of 20 to enhance performance.

 

2 实验 

--用户要有CREATE SEQUENCE 权限,否则提示ORA-01031: insufficient privileges"错误
SQL> CONN / AS SYSDBA
Connected.
SQL> ALTER SESSION SET CONTAINER=pdbcndba;

Session altered.

SQL> GRANT CREATE TABLE, CREATE SEQUENCE TO cndba;

Grant succeeded.

SQL> CONN cndba/cndba@pdbcndba
Connected.
--当强制使用 ALWAYS 时,null和指定值时都会报错,原因是当使用ALWAYS时,字段值只能使用序列
SQL> DROP TABLE cndba PURGE;

Table dropped.

SQL> CREATE TABLE cndba (
  id          NUMBER GENERATED ALWAYS AS IDENTITY,
  description VARCHAR2(30)
);  2    3    4  

Table created.

SQL> INSERT INTO cndba (description) VALUES ('Just DESCRIPTION');  
  2  
SQL> INSERT INTO cndba (description) VALUES ('Just DESCRIPTION');

1 row created.

SQL> INSERT INTO cndba (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');
INSERT INTO cndba (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION')
                   *
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column


SQL> INSERT INTO cndba (id, description) VALUES (999, 'ID=999 and DESCRIPTION');
INSERT INTO cndba (id, description) VALUES (999, 'ID=999 and DESCRIPTION')
                   *
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column

--当使用BY DEFAULT 时,指定null值时会提示错误,因为标识列总是不为空的。 SQL> DROP TABLE cndba PURGE;

Table dropped.

SQL> CREATE TABLE cndba (
  id          NUMBER GENERATED BY DEFAULT AS IDENTITY,
  description VARCHAR2(30)
);  2    3    4  

Table created.

SQL> INSERT INTO cndba (description) VALUES ('Just DESCRIPTION');

1 row created.

SQL> INSERT INTO cndba (id, description) VALUES (999, 'ID=999 and DESCRIPTION');

1 row created.

SQL> INSERT INTO cndba (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');
INSERT INTO cndba (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION')
                                            *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("CNDBA"."CNDBA"."ID")

--当使用 BY DEFAULT ON NULL时,null 值时可以指定的。 SQL> DROP TABLE cndba PURGE;

Table dropped.

SQL> CREATE TABLE cndba (
  id          NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
  description VARCHAR2(30)
);  2    3    4  

Table created.

SQL> INSERT INTO cndba (description) VALUES ('Just DESCRIPTION');

1 row created.

SQL> INSERT INTO cndba (id, description) VALUES (999, 'ID=999 and DESCRIPTION');

1 row created.

SQL> INSERT INTO cndba (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');

1 row created.

SQL> SELECT * FROM cndba;

	ID DESCRIPTION
---------- ------------------------------
	 1 Just DESCRIPTION
       999 ID=999 and DESCRIPTION
	 2 ID=NULL and DESCRIPTION

--基于创建序列特权的需求,一个序列被用来填充标识列。 SQL> ALTER SESSION SET CONTAINER=pdbcndba;

Session altered.
SQL>  COLUMN object_name FORMAT A20
SQL> SELECT object_name, object_type
FROM   user_objects;  2  

OBJECT_NAME	     OBJECT_TYPE
-------------------- -----------------------
T1		     TABLE
ISEQ$$_79359	     SEQUENCE
ISEQ$$_79371	     SEQUENCE
CNDBA		     TABLE

--[DBA|ALL|USER]_TAB_IDENTITY_COLS 表中查看identity columns信息 SQL> SET LINESIZE 100
SQL> COLUMN table_name FORMAT A20 
SQL> COLUMN column_name FORMAT A15
SQL> COLUMN generation_type FORMAT A10
SQL> COLUMN identity_options FORMAT A50
SQL> SELECT table_name, 
       column_name,
       generation_type,
       identity_options
FROM   all_tab_identity_cols
WHERE  owner = 'CNDBA'
ORDER BY 1, 2;  2    3    4    5    6    7  

TABLE_NAME	     COLUMN_NAME     GENERATION IDENTITY_OPTIONS
-------------------- --------------- ---------- --------------------------------------------------
CNDBA		     ID 	     BY DEFAULT START WITH: 1, INCREMENT BY: 1, MAX_VALUE: 9999999
						999999999999999999999, MIN_VALUE: 1, CYCLE_FLAG: N
						, CACHE_SIZE: 20, ORDER_FLAG: N
						

--表和序列之间的链接存储在SYS.IDNSEQ$表中 SQL> CONN / AS SYSDBA
Connected.
SQL> ALTER SESSION SET CONTAINER=pdbcndba;

Session altered.

SQL> COLUMN sequence_name FORMAT A30                               
SQL> SELECT a.name AS table_name,
       b.name AS sequence_name
FROM   sys.idnseq$ c
       JOIN sys.obj$ a ON c.obj# = a.obj#
       JOIN sys.obj$ b ON c.seqobj# = b.obj#;  2    3    4    5  

TABLE_NAME	     SEQUENCE_NAME
-------------------- ------------------------------
T1		     ISEQ$$_79357
T1		     ISEQ$$_79359
CNDBA		     ISEQ$$_79371

--在执行计划值中可以看到序列被使用
SQL> SET AUTOTRACE ON
SQL> SET LINESIZE 200
SQL> INSERT INTO cndba (description) VALUES ('Just DESCRIPTION');

1 row created.


Execution Plan
----------------------------------------------------------
Plan hash value: 372728000

-----------------------------------------------------------------------------------
| Id  | Operation		 | Name   | Rows  | Bytes | Cost (%CPU)| Time	  |
-----------------------------------------------------------------------------------
|   0 | INSERT STATEMENT	 |	  |	1 |   100 |	1   (0)| 00:00:01 |
|   1 |  LOAD TABLE CONVENTIONAL | CNDBA  |	  |	  |	       |	  |
|   2 |   SEQUENCE		 | CN_SEQ |	  |	  |	       |	  |
-----------------------------------------------------------------------------------


Statistics
----------------------------------------------------------
	 58  recursive calls
	  6  db block gets
	 56  consistent gets
	  0  physical reads
	572  redo size
	848  bytes sent via SQL*Net to client
	979  bytes received via SQL*Net from client
	  3  SQL*Net roundtrips to/from client
	  6  sorts (memory)
	  0  sorts (disk)
	  1  rows processed

参考链接:

http://docs.oracle.com/database/121/DRDAA/migr_tools_feat.htm#DRDAA109

https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值