oracle增加字段为主键自增_在 Oracle 中设置自增列
如果你經(jīng)常使用 MySQL,你肯定對 AUTO_INCREMENT 非常熟悉,因為經(jīng)常要用到它。
一、什么是自增列 ?
自增列是數(shù)據(jù)庫中值隨插入的每個行自動增加的一列。它最常用于主鍵或 ID 字段,這樣每次增加一行時,不用指該字段的值,它就會自動增加,而且是唯一的。
當(dāng)在 MySQL 中定義列時,我們可以指定一個名為 AUTO_INCREMENT 的參數(shù)。然后,每當(dāng)將新值插入此表中時,放入此列的值比最后一個值加 1。
但很不幸,Oracle 沒有 AUTO_INCREMENT 功能。 那要如何在Oracle中做到這一點呢?
二、在 Oracle 11g 中設(shè)置自增字段
1. 創(chuàng)建表
首先創(chuàng)建一張用于測試的表:
CREATE TABLE "TEST" (
ID NUMBER(11) PRIMARY KEY,
NAME VARCHAR2(50BYTE) NOT NULL
);
2. 創(chuàng)建序列
然后創(chuàng)建一個名為 TEST_ID_SEQ 的序列(序列名稱自己隨意設(shè)定):
CREATE SEQUENCE TEST_ID_SEQ
INCREMENT BY 1
START WITH 100
MAXVALUE 999999999
NOCYCLE
NOCACHE;
如果要刪除序列,可以使用下面的 SQL 命令:
DROP SEQUENCE TEST_ID_SEQ;
對 SEQUENCE 的一些說明:INCREMENT BY 用于指定序列增量(默認(rèn)值:1),如果指定的是正整數(shù),則序列號自動遞增,如果指定的是負(fù)數(shù),則自動遞減。
START WITH 用于指定序列生成器生成的第一個序列號,當(dāng)序列號順序遞增時默認(rèn)值為序列號的最小值,當(dāng)序列號順序遞減時默認(rèn)值為序列號的最大值。
MAXVALUE 用于指定序列生成器可以生成的組大序列號(必須大于或等于 START WITH,并且必須大于 MINVALUE),默認(rèn)為 NOMAXVALUE。
MINVALUE 用于指定序列生成器可以生成的最小序列號(必須小于或等于 START WITH,并且必須小于 MAXVALUE),默認(rèn)值為 NOMINVALUE。
CYCLE 用于指定在達(dá)到序列的最大值或最小值之后是否繼續(xù)生成序列號,默認(rèn)為 NOCYCLE。
CACHE 用于指定在內(nèi)存中可以預(yù)分配的序列號個數(shù)(默認(rèn)值:20)。
到這一步其實就已經(jīng)可以實現(xiàn)字段自增,只要插入的時候,將 ID 的值設(shè)置為序列的下一個值 TEST_ID_SEQ.NEXTVAL 就可以了:
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (TEST_ID_SEQ.NEXTVAL, 'name1');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (TEST_ID_SEQ.NEXTVAL, 'name2');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (TEST_ID_SEQ.NEXTVAL, 'name3');
SQL> SELECT * FROM "TEST";
ID NAME
--- ------100name1
101name2
102name3
為了簡化插入操作,我們還可以創(chuàng)建一個觸發(fā)器,當(dāng)將數(shù)據(jù)插入到 “TEST” 表的時候,自動將最新的 ID 插入進(jìn)去。
3. 創(chuàng)建觸發(fā)器
CREATE OR REPLACE TRIGGER TEST_ID_SEQ_TRG
BEFORE INSERT ON "TEST"
FOR EACH ROW
WHEN (NEW."ID" IS NULL)
BEGIN
SELECT TEST_ID_SEQ.NEXTVAL
INTO :NEW."ID"
FROM DUAL;
END;
這樣的話,每次寫插入語句,只需要將 ID 字段的值設(shè)置為 NULL 它就會自動遞增了:
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name4');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name5');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name6');
SQL> SELECT * FROM "TEST";
ID NAME
--- ------100name1
101name2
102name3
103name4
104name5
105name6
4. 一些值得注意的地方
4.1 插入指定 ID
如果某條插入語句指定了 ID 的值如:
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (1000, 'name1001');
SQL> SELECT * FROM "TEST";
ID NAME
--- ------100name1
101name2
102name3
103name4
104name5
1000name1001
那么下次 ID 還是會在原來的基礎(chǔ)上繼續(xù)增加:
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name1001');
SQL> SELECT * FROM "TEST";
ID NAME
--- ------100name1
101name2
102name3
103name4
104name5
1000name1001
但當(dāng)序列的值到了 1000 的時候,如果 ID 允許重復(fù),就會有兩行記錄 ID 都為 1000。
但如果 ID 設(shè)置為了主鍵,如本文的例子 ID NUMBER(11) PRIMARY KEY,則插入就會報錯:
Error : ORA-00001: unique constraint (SOFTWARE.SYS_C0014995) violated
4.2 字段加引號
在 SQL 語句中,字段最好都加上引號,不然可能會報錯:
Error : ORA-00900: invalid SQL statement
或:
ORA-24344: Success with Compilation Error
4.3 SQUENCE第一次 NEXTVAL 返回的是初始值;隨后的 NEXTVAL 會自動增加 INCREMENT BY 對應(yīng)的值,然后返回增加后的值。
CURRVAL 總是返回當(dāng)前 SEQUENCE 的值,但是在第一次 NEXTVAL 初始化之后才能使用 CURRVAL ,否則會出錯。
一次 NEXTVAL 會增加一次 SEQUENCE 的值,所以如果在同一個語句里面使用多個NEXTVAL,其值就是不一樣的。
如果指定 CACHE 值,Oracle 就可以預(yù)先在內(nèi)存里面放置一些 SEQUENCE,這樣存取的快些。 CACHE 里面的取完后,Oracle 自動再取一組到 CACHE。
但使用 CACHE 或許會跳號,比如數(shù)據(jù)庫突然不正常關(guān)閉(shutdown abort), CACHE 中的 SEQUENCE 就會丟失。所以可以在 CREATE SEQUENCE 的時候用 NOCACHE 防止這種情況。
4.4 性能
在數(shù)據(jù)庫操作中,觸發(fā)器的使用耗費系統(tǒng)資源相對較大。如果對于表容量相對較小的表格我們可以忽略觸發(fā)器帶來的性能影響。
考慮到大表操作的性能問題,需要盡可能的減少觸發(fā)器的使用。對于以上操作,就可以拋棄觸發(fā)器的使用,直接手動調(diào)用序列函數(shù)即可,但這樣可能在程序維護(hù)上稍微帶來一些不便。
三、在 Oracle 12c 中設(shè)置自增字段
在 Oracle 12c 中設(shè)置自增字段就簡單多了,因為 ORacle 12c 提供了 IDENTITY 屬性:
CREATE TABLE "TEST" (
ID NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY,
NAME VARCHAR2(50BYTE) NOT NULL
);
這樣就搞定了!和 MySQL 一樣簡單!???
四、總結(jié)
所以如上所屬,在 Oracle 中設(shè)置自增字段,需要根據(jù)不同的版本使用不同的方法:在 Oracle 11g 中,需要先創(chuàng)建序列(SQUENCE)再創(chuàng)建一個觸發(fā)器(TRIGGER)。
在 Oracle 12c 中,只需要使用 IDENTITY 屬性就可以了。
總結(jié)
以上是生活随笔為你收集整理的oracle增加字段为主键自增_在 Oracle 中设置自增列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu Linux系统下搭建自己的
- 下一篇: 用 Kaggle 经典案例教你用 CNN