Oracle 12c提供的Identity Column特性簡化了自增字段的定義。
聲明自增字段通常有3種常見的用法,以下三種方式都支持INSERT
語句中省略自增字段的插入,但有些許差別。
1. GENERATED [ALWAYS] AS IDENTITY
此時ALWAYS
關鍵字是可選的:
create table tb_test (
id number GENERATED ALWAYS AS IDENTITY,
name varchar2(100)
);
此時試圖插入指定ID
字段的元組將報錯,因為ID
字段總是自動生成的,例如,執行下述語句:
INSERT INTO TB_TEST VALUES(1, 'Zyon');
將報:
ORA-32795: 無法插入到“始終生成”身份列
2. GENERATED BY DEFAULT AS IDENTITY
create table tb_test2 (
id number GENERATED BY DEFAULT AS IDENTITY,
name varchar2(100)
);
此時可以插入指定ID
列的元組,但不能指定ID
列為NULL
。
如:下述語句正常執行
INSERT INTO TB_TEST2 VALUES(1, 'Zyon');
但如下語句將會報錯:
INSERT INTO TB_TEST2 VALUES(NULL, 'Darren');
3. GENERATED BY DEFAULT ON NULL AS IDENTITY
create table tb_test3 (
id number GENERATED BY DEFAULT on null AS IDENTITY,
name varchar2(100)
);
此時可以插入指定ID
列的元組,也可以指定插入ID
列為NULL
。
如下語句正常執行:
INSERT INTO TB_TEST3 VALUES(NULL, 'Darren');
注意
當自增列還要求唯一時,上述情形2和情形3將帶來一個問題。
上述情形2和情形3允許插入指定自增列的元組,同時自增列自增時維護着下一次將要生成的序列號。所以如果同時支持自增,又插入了某個指定序列號的元組,后續插入時如果忽略自增列,那么當自增序列號達到指定序列號時,將會出現插入失敗的情形。
但是此時自增計數器繼續增加,所以下一次忽略自增列的插入可能又恢復正常,除非下一個序列號也被指定插入占用了。
例如:
忽略ID
字段插入了9個元組(ID
取值1-9),突然指定ID
為10插入第10個元組,然后又忽略ID
字段插入時,因為10已經被占用,如果自增列要求唯一,將會出現沖突。
所以最好還是統一插入時SQL的形式,不要混用。
參考:
http://www.xifenfei.com/2015/03/oracle-12c-新特性identity-columns-實現oracle自增長列功能.html