序列sequence:
如果要查employees表中id的最大值
select max(employee_id) from employees;
但是如果要保證主鍵插入的唯一性的話,如果使用max(employee_id) + 1
的方式是不能避免不重複的,因為可能會遇到並行作業的問題,兩個人同時
插入都加了1,結果插入的employee_id重複了
另外一種方式是讓主鍵設為自增列:在oracle中是無法用sql語句實現子增的,
只能通過觸發器來實現!
還有一種方式就是序列了:
例:建立一個序列來自動產生序號
create sequence 序列名
increment by n
start with n
maxvalue n | nomaxvalue
minvalue n | nominvalue
cycle | nocycle
cache n | nocache; 預設緩衝20個。
舉例說明:
create sequence seq_a
start with 1 預設從1開始
maxvalue 11
increment by 10 ;
這個序列從1到11,每次遞增值為10
建立序列後,從中往出取值,取值要用到兩個偽列,一個叫做nextval
另外一個叫做currval
select seq_a.currval from dual;
執行失敗,任何一個序列的第一次執行必須是nextval不能是currval。
select seq_a.nextval from dual;
第一次執行上述語句是1,第二次執行就是11了。
如果要設置迴圈的話,cache值必須小於cycle值,注意cache的值必須大於1
alter sequence seq_a
maxvalue 21
cycle
cache 2
更改了序列後
執行select seq_a.nextval from dual;後
顯示的是21,在執行相同的語句後,就是1了
,再執行的話是11,再執行就是21,因為設置了迴圈
所以會從1到21迴圈的來,每一次都加10。
如果要查看序列的話
輸入desc seq就可以
然後,select sequence_name from seq ,可以找到序列名。
這時要往employees表中插入主鍵的話,不要往主鍵裡面插入記錄中沒有
出現的值,雖然可以插進去,但這是很危險的,以後會和序列衝突的!!
insert into employees(employee_id,last_name,email,hire_date,
job_id) values(employees_seq.nextval,'aaa','ccc',
sysdate,2,'IT_PROG');
採用主鍵序列的nextval方式肯定可以保證主鍵的值不重複而且符合序列,
這時可用
select employees_seq.currval from dual;
可以查出當前的主鍵序列值,假如是207的話。
注意:插入即便失敗了,序列值也會跟著增加的。
假設下面一個人進行了插入主索引值為208的操作,但是沒有用nextval,再下面
一個人規矩的按照nextval方法插入的話就會出現違反主鍵唯一性限制式的情況。
其實就是直接指明主鍵插入的話不會更改序列值,除非使用
employees_seq.nextval,
注意插入時如果使用了employees_seq.nextval,不管插入成功與否,
序列都會增加,而且序列值不會受交易回復的影響!!
事務對sequence是無法恢複的,所以就會出現跳值的現象,就如同子增的跳值
是一樣的,實質都一樣,子增的實質也是序列,也是不管插入與否,都會子增。
實際資料庫中也是無法避免跳數現象的,主鍵插入就是用nextval方法去作。
注意序列的nextval是完全可以避免並發衝突的,因為裡面有並發機制在裡面,
不會出現兩個人同時nextval,但是取出了相同值的情況。
交易回復、系統崩潰、兩個或多個表共用一個sequence時,會發生序列跳
數的情況。