实际应用中,很多时候,我们会利用序列来填充主键列。毕竟,序列恰好是满足主键的唯一和非空约束的。当然,如果该序列为nocycle的话。
从12c开始,我们可以在创建表时,就对这样的列进行设置,让它像序列一样,自动增长。
数据库版本12.1.0.2,操作系统为OEL 7.1 64位。
创建包含自增长列的测试表:
TEST1@ora12> create table tab_test (
2 id numbergenerated as identity,
3 name varchar2(30));
Table created.
插入数据并查看:
TEST1@ora12> INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])tab_test (name) values (1);
1 row created.
TEST1@ora12> INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])tab_test (name) values (2);
1 row created.
TEST1@ora12> select * from tab_test;
ID NAME
---------- ------------------------------
1 1
2 2
在创建包含自增长列的表时,oracle会自动创建一个序列,并将其绑定到该列上。
TEST1@ora12> col SEQUENCE_NAME for a30
TEST1@ora12> select sequence_name,min_value,increment_by,max_value from user_sequences;
SEQUENCE_NAME MIN_VALUE INCREMENT_BY MAX_VALUE
----------------------- ---------- ------------ ----------
ISEQ$$_91998 1 1 1.0000E+28
对应的数据字典表也有调整:
TEST1@ora12> desc user_tab_columns;
Name Null? Type
----------------------------------------- -------- ----------------------------
TABLE_NAME NOT NULL VARCHAR2(128)
COLUMN_NAME NOT NULL VARCHAR2(128)
DATA_TYPE VARCHAR2(128)
DATA_TYPE_MOD VARCHAR2(3)
DATA_TYPE_OWNER VARCHAR2(128)
DATA_LENGTH NOT NULL NUMBER
DATA_PRECISION NUMBER
DATA_SCALE NUMBER
NULLABLE VARCHAR2(1)
COLUMN_ID NUMBER
DEFAULT_LENGTH NUMBER
DATA_DEFAULT LONG
NUM_DISTINCT NUMBER
LOW_VALUE RAW(1000)
HIGH_VALUE RAW(1000)
DENSITY NUMBER
NUM_NULLS NUMBER
NUM_BUCKETS NUMBER
LAST_ANALYZED DATE
SAMPLE_SIZE NUMBER
CHARACTER_SET_NAME VARCHAR2(44)
CHAR_COL_DECL_LENGTH NUMBER
GLOBAL_STATS VARCHAR2(3)
USER_STATS VARCHAR2(3)
AVG_COL_LEN NUMBER
CHAR_LENGTH NUMBER
CHAR_USED VARCHAR2(1)
V80_FMT_IMAGE VARCHAR2(3)
DATA_UPGRADED VARCHAR2(3)
HISTOGRAM VARCHAR2(15)
DEFAULT_ON_NULL VARCHAR2(3)
IDENTITY_COLUMN VARCHAR2(3)
EVALUATION_EDITION VARCHAR2(128)
UNUSABLE_BEFORE VARCHAR2(128)
UNUSABLE_BEGINNING VARCHAR2(128)
IDENTITY_COLUMN,即显示了是否为自增长列。
如下:
TEST1@ora12> col TABLE_NAME for a20
TEST1@ora12> col COLUMN_NAME for a20
TEST1@ora12> select table_name,column_name,identity_column from user_tab_columns;
TABLE_NAME COLUMN_NAME IDE
-------------------- -------------------- ---
TAB_TEST NAME NO
TAB_TEST ID YES
测试插入:
TEST1@ora12> INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])tab_test values (3,3);
INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])tab_test values (3,3)
*
ERROR at line 1:
ORA-32795: cannot INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])a generated always identity column
这样就不行。
我们需要对该列的定义做调整
TEST1@ora12> alter table tab_test modify idgenerated by default on null as identity;
Table altered.
TEST1@ora12> INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])tab_test values (3,3);
1 row created.
这样,当我们设置该列的值时,就使用我们提供的值,否则,就使用所绑定的序列自动生成的值。
TEST1@ora12> INSERT INTO dbo.teacher_report_infos_detail ([teacher_report_id],[detail])tab_test(name) values (4);
1 row created.
TEST1@ora12> select * from tab_test;
ID NAME
---------- ------------------------------
1 1
2 2
3 3
34
注意这个3。
但是这样使用,会有一个问题,也就是,oracle自动生成并绑定到自增长列的序列,是有其自身的默认设置的:起始值为1,步长为1。
如果我们觉得这种默认设置不符合我们的需求,则需要做调整:
TEST1@ora12> create table tab_test2(
2 id number generated as identity (
3start with 50 increment by 2),
4 name varchar2(30));
Table created.
包含自增长列的表相关注意事项:
1,一张表中,只能有一列为自增长列。
TEST1@ora12> create table tab_test3(
2 id number generated as identity (
3 start with 50 increment by 2),
4 id2 number generated as identity (
5 start with 50 increment by 2),
6 name varchar2(30));
ERROR at line 1:
ORA-30669:table can have only one identity column
2,列的数据类型,必须为数值型。
3,不能设置默认值。
4,会自动应用not null和not deferrable
5,使用CTAS方式无法继承自增长列的属性。
6,如果执行回滚,事务会回滚,但是序列中的值不会回滚。