MySQL實現類似Oracle的序列
Oracle一般使用序列(Sequence)來處理主鍵字段,而MySQL則提供了自增長(increment)來實現類似的目的;
但在實際使用過程中發現,MySQL的自增長有諸多的弊端:不能控制步長、開始索引、是否循環等;若需要遷移
數據庫,則對於主鍵這塊,也是個頭大的問題。
本文記錄了一個模擬
Oracle序列的方案,重點是想法,代碼其次。
Oracle序列的使用,無非是使用.nextval和.currval偽列,基本想法是:1、MySQL中新建表,用於存儲序列名稱和值;2、創建函數,用於獲取序列表中的值;
具體如下:
表結構為
[sql]
表結構為:
1
2
3
4
5
6
7
|
drop
table
if exists
sequence
;
create
table
sequence
(
seq_name
VARCHAR
(50)
NOT
NULL
,
current_val
INT
NOT
NULL
,
increment_val
INT
NOT
NULL
DEFAULT
1,
PRIMARY
KEY
(seq_name)
);
|
實現currval的模擬方案
1
2
3
4
5
6
7
8
9
10
11
|
[sql]
create
function
currval(v_seq_name
VARCHAR
(50))
returns
integer
begin
declare
value
integer
;
set
value = 0;
select
current_value
into
value
from
sequence
where
seq_name = v_seq_name;
return
value;
end
;
|
[sql]
函數使用為:select currval('MovieSeq');
實現nextval的模擬方案
1
2
3
4
5
6
7
8
9
|
[sql]
create
function
nextval (v_seq_name
VARCHAR
(50))
return
integer
begin
update
sequence
set
current_val = current_val + increment_val
where
seq_name = v_seq_name;
return
currval(v_seq_name);
end
;
|
[sql]
函數使用為:select nextval('MovieSeq');
增加設置值的函數
1
2
3
4
5
6
7
8
|
[sql]
create
function
setval(v_seq_name
VARCHAR
(50), v_new_val
INTEGER
)
returns
integer
begin
update
sequence
set
current_val = v_new_val
where
seq_name = v_seq_name;
return
currval(seq_name);
|
同理,可以增加對步長操作的函數,在此不再敘述。
注意語法,數據庫字段要對應上
use bvboms;
DELIMITER $$
create function setval(v_seq_name VARCHAR(50), v_new_val INTEGER)
returns integer
begin
update sequence
set current_val = v_new_val
where seq_name = v_seq_name;
return currval(seq_name);
end $$
DELIMITER $$