签到成功

知道了

CNDBA社区CNDBA社区

Oracle 12c Identity Columns 新特性 和 序列 构成自增列

2016-09-06 01:16 4449 0 原创 Oracle 18c
作者: dave


http://www.cndba.cn/dave/article/219

1    Identity Columns 说明

    在Oracle 12c 之前,表中的列是没有自增功能的,所以要想实现主键的自增,通常的做法是先创建一个序列,在创建一个触发器,来实现自增,在Oracle 12c 中,Oracle 解决了这个问题, Identity Columns的新特性,实现了自增列的功能。

    关于Oracle 12c序列的操作,可以直接查看官方手册,有详细的说明。 我们这里重点测试identity columns。

    Identity Columns 是自动增加的列,该特性使用默认的序列生成器来强制表列序列按递增或者递减的值来分别值。http://www.cndba.cn/dave/article/219

SQL> create table cndba (
id1 number generated by default as identity ,
name varchar2(50)
);
Table created.

SQL> insert into cndba(name) values ('tianlesoftware');
1 row created.
SQL> insert into cndba(name) values ('http://cndba.cn');
1 row created.
SQL> insert into cndba(name) values ('http://ahdba.cn');
1 row created.
SQL> commit;
Commit complete.

SQL> select * from cndba;
       ID1 NAME
---------- -----------------------------------------------
     1 tianlesoftware
     2 http://cndba.cn
     3 http://ahdba.cn这里id列成功的使用默认的序列生成器来自增。




2    使用generated by default

除了使用默认的序列生成器之外,也可以使用指定的序列来自增,或者仅当插入NULL 的时候才自增。

在语法上,如采用generated by default就是采用默认的序列生成器,此时用户可以插入自己的值,如果使用GENERATED ALWAYS 就是使用特定的序列,此时自增列只能使用序列生成器提供的值,用户无法更改自增列。

如果在添加ON Null 选项,则表示仅当插入NULL时,才会自增。

示例:

SQL> create table ahdba (
id1 number generated by default as identity ,
name varchar2(50)
);
Table created.

SQL> insert into ahdba(name) values ('http://ahdba.com');
1 row created.
SQL> insert into ahdba values(100,'dave');
1 row created.
SQL> commit;
Commit complete.
--注意这里,用户可以插入自增列。

SQL> insert into ahdba values (NULL,'tianlesoftware');
 insert into ahdba values (NULL,'tianlesoftware')
                           *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SYS"."AHDBA"."ID1")


SQL> select * from ahdba;
       ID1 NAME
---------- --------------------------------------------------
     1 http://ahdba.com
       100 dave




创建仅插入NULL 时才自增的对象:

create table huaining (
id1 number generated by default on NULL as identity ,
name varchar2(50));

SQL> desc huaining
Name Null? Type
----------------------------------------- -------- ----------------------------
ID1 NOT NULL NUMBER
NAME VARCHAR2(50)

SQL> insert into huaining values (1, '安庆');
1 row created.

SQL> insert into huaining values(20,'怀宁');
1 row created.

SQL> insert into huaining values (NULL,'月山');
1 row created.

SQL> insert into huaining values (NULL,'合肥');
1 row created.

SQL> commit;
Commit complete.

SQL> select * from huaining;

       ID1 NAME
---------- --------------------------------------------------
     1 安庆
    20 怀宁
     1 月山
     2 合肥


可以看到上面的结果,只有最后2条记录自增了,其他2条记录,采用了我们指定的值。


3    使用Generated Always
    上面的实验都是采用默认的序列生成器来自增,也可以使用Generated Always的方式指定独立的序列规则,如果指定为generated always,那么列就不能被用户更新,只能使用序列生成器提供的值。

示例:http://www.cndba.cn/dave/article/219

http://www.cndba.cn/dave/article/219

create table aniqng (
id1 number generated always as identity ,
name varchar2(50));

SQL> desc anqing
 Name                       Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID1                       NOT NULL NUMBER
 NAME                            VARCHAR2(50)


SQL>  insert into anqing values (1,'aniqng');
 insert into anqing values (1,'aniqng')
*
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column

SQL> !oerr ora 32795
32795,0000, "cannot insert into a generated always identity column"
// *Cause:  An attempt was made to insert a value into an identity column
//          created with GENERATED ALWAYS keywords.
// *Action: A generated always identity column cannot be directly inserted.
//          Instead, the associated sequence generator must provide the value.


SQL> insert into anqing values (NULL,'dave');
insert into anqing values (NULL,'dave')
*
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column


SQL> insert into anqing (name) values ('安庆');
1 row created.
SQL> insert into anqing (name) values ('怀宁');
1 row created.
SQL> insert into anqing (name) values ('月山');
1 row created.
SQL> commit;
Commit complete.

SQL> select * from anqing;

       ID1 NAME
---------- --------------------------------------------------
     1 安庆
     2 怀宁
     3 月山


SQL> update anqing set id1=4 where id1=2;
update anqing set id1=4 where id1=2
                  *
ERROR at line 1:
ORA-32796: cannot update a generated always identity column



4    修改Identity Columns

可以在创建table时指定identity columns的类型和规则,也可以创建之后使用alter table 来修改,生成器的规则在identity选择中指定。http://www.cndba.cn/dave/article/219http://www.cndba.cn/dave/article/219

create table yueshan (
id1 number generated always as identity (start with 8 increment by 3),
name varchar2(50)
);

SQL> insert into yueshan (name) values ('安庆');
SQL> insert into yueshan (name) values ('月山');
SQL> commit;

SQL> select * from yueshan;

       ID1 NAME
---------- --------------------------------------------------
     8 安庆
    11 月山


注意这里的序列开始值和增加的间隔。


可以使用如下SQL 查看identity columns 对应的序列。http://www.cndba.cn/dave/article/219http://www.cndba.cn/dave/article/219

http://www.cndba.cn/dave/article/219

SQL> col table_name for a20
SQL> col COLUMN_NAME for a20
SQL>set lin 130

SQL> select table_name,column_name,default_on_null,identity_column,data_default from user_tab_columns where table_name in ('ANIQNG','HUAINING','YUESHAN','CNDBA');

TABLE_NAME         COLUMN_NAME                  DEF IDE DATA_DEFAULT
-------------------- ---------------------------------------- --- --- ------------------------------
CNDBA             ID1                      NO  YES "SYS"."ISEQ$$_92197".nextval
CNDBA             NAME                      NO  NO
HUAINING         ID1                      YES YES "SYS"."ISEQ$$_92201".nextval
HUAINING         NAME                      NO  NO
YUESHAN          ID1                      NO  YES "SYS"."ISEQ$$_92205".nextval
YUESHAN          NAME                      NO  NO

6 rows selected.





5    12c 中Identity columns的限制

1.    一张表里只能有一个identity column。
2.    Identity column 的类型只能是number,不能是用户定义的类型。
3.    对identity column的表进行CTAS 复制时不会继承identity column的属性。
4.    创建identity column时,不能指定DEFAULT 默认值。
5.    Identity column列默认包含not null 和non deferrable约束。
http://www.cndba.cn/dave/article/219


版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2284
    原创
  • 3
    翻译
  • 580
    转载
  • 197
    评论
  • 访问:8206938次
  • 积分:4433
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ