轉自:https://blog.csdn.net/zxh2075/article/details/78488141
之前有一項工作是將mysql的數據庫實現轉移到oracle,遇到了自增主鍵實現的問題。
首先介紹一下MySQL和Oracle的背景知識
1)MySQL建表時必須有一個主鍵(PRIMARY KEY), 每條主鍵內容必須唯一(Unique), 所以經常使用一個”ID”字段作為主鍵,給它一個”auto_increment”屬性,讓”ID”字段每條記錄都自增”1″。
比如下表:
1 CREATE TABLE Demo 2 ( 3 id INT NOT NULL auto_increment PRIMARY KEY, 4 key1 VARCHAR2(40) NULL, 5 key2 VARCHAR2(40) NULL 6 );
id是自增主鍵。
insert 的時候,用不着理會自增主鍵的value,插入新項時會自動給id賦值,插入新紀錄時用不着考慮自增主鍵。
1 insert into Demo(key1, key2) 2 value("k1","k2")
如果是第一條紀錄,插入的數據項為
id | key1 | key2
1 | k1 | k2
2)Oracle沒有這個”auto_increment”屬性,所以它沒法像MySQL般在表內定義自增主鍵。
但是,Oracle里的序列(SEQUENCE),可間接實現自增主鍵的作用。
序列(Sequence),又叫序列生成器,用於提供一系列的數字,開發人員使用序列生成唯一鍵。每次訪問序列,序列按照一定的規律增加或者減少。
序列的定義存儲在SYSTEM表空間中,序列不像表,它不會占用磁盤空間。
序列獨立於事務,每次事務的提交和回滾都不會影響序列。
創建的方法及參數說明如下,想了解更多,可以具體查一下oracle database sequence的說明:
1 CREATE SEQUENCE SEQNAME //序列名字 2 INCREMENT BY 1 //每次自增1, 也可寫非0的任何整數,表示自增,或自減 3 START WITH 1 //以該值開始自增或自減 4 MAXVALUE 1.0E20 //最大值;設置NOMAXVALUE表示無最大值 5 MINVALUE 1 //最小值;設置NOMINVALUE表示無最大值 6 CYCLE or NOCYCLE //設置到最大值后是否循環; 7 CACHE 20 //指定可以緩存 20 個值在內存里;如果設置不緩存序列,則寫NOCACHE 8 ORDER or NOORDER //設置是否按照請求的順序產生序列
oracle實現自增主鍵,如上例,其表的創建語句如下:
1 CREATE TABLE Demo 2 ( 3 id INT NOT NULL PRIMARY KEY, 4 key1 VARCHAR2(40) NULL, 5 key2 VARCHAR2(40) NULL 6 );
沒有auto_increment屬性了。
插入時實現自增主鍵,先創建序列:
1 CREATE SEQUENCE SEQ 2 INCREMENT BY 1 3 START WITH 1 4 MAXVALUE 1.0E20 5 MINVALUE 1 6 NOCYCLE 7 CACHE 20 8 NOORDER
插入時:
1 insert into Demo(id, key1, key2)
2 value(SEQ.NEXTVAL,"k1","k2")
然而,上述方法不適用於insert的另一種使用方式;即
1 insert into table(key1, key2) select k1, k2 from anotherTable;
所以真正設計時,應該用觸發器保證自增主鍵的實現,如下過程:
下面用一個例子來說明自增主鍵的創建:
1、建用戶數據表
1 drop table dectuser; 2 create table dectuser( 3 userid integer primary key, /*主鍵*/ 4 name varchar2(20), 5 sex varchar2(2) 6 );
2、創建自動增長序列
1 drop sequence dectuser_tb_seq; 2 create sequence dectuser_tb_seq minvalue 1 maxvalue 99999999 3 increment by 1 4 start with 1; /*步長為1*/
3、創建觸發器
1 create or replace trigger dectuser_tb_tri 2 before insert on dectuser /*觸發條件:當向表dectuser執行插入操作時觸發此觸發器*/ 3 for each row /*對每一行都檢測是否觸發*/ 4 begin /*觸發器開始*/ 5 select dectuser_tb_seq.nextval into :new.userid from dual; 6 /*觸發器主題內容,即觸發后執行的動作,在此是取得序列dectuser_tb_seq的下一個值插入到表dectuser中的userid字段中*/ 7 end; 8 /
4、提交
現在就完成了自增主鍵的設定,搞定!可以檢測一下。
1 insert into dectuser(name,sex) values ('feng','男); 2 commit; /*提交*/
提示“已創建一行”,表示成功。
上述示例的代碼,是直接引用他人的文章內容;原貼在
http://shanxmxj.javaeye.com/blog/948739
自己試過此方法,但對select into感覺還是有些地方理解得不好。