现在都在流行去oracle化,由于oracle没有自增主键这种东西,很多项目在使用oracle时用序列去维护主键。
在迁移mysql后,某些需要提前拿到自增序列并增加自增序列的场景在msyql中就不支持了
-- 函数说明
-- get_now_and_seize(
-- 入参:表名(varchar),
-- 入参:占多少个,防止新插入的占了拿到的主键值(int),
-- 出参:下一个即将插入的主键值(int));
CREATE PROCEDURE get_now_and_seize(IN v_table_name VARCHAR(50),IN inc_num int, OUT now_auto int)
BEGIN
-- 开启事务
start transaction;
-- 获取下一个即将插入的主键值
select auto_increment into now_auto from INFORMATION_SCHEMA.TABLES where TABLE_NAME = v_table_name limit 1;
-- 编写动态sql,占位
set @sql_1= concat("alter table ",v_table_name," AUTO_INCREMENT=",now_auto+inc_num,";");
PREPARE stmt FROM @sql_1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
commit;
END
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 插入一些老数据做测试
insert into test (name) value ("ID为1的老数据");
select * from test;
id | name
-----|---------------
1 | ID为1的老数据
-- 开始调用获取下一个插入数据的ID并占用多少个的函数
call get_now_and_seize("test",10,@now_seq);
-- 返回2
select @now_seq;
insert into test (name) value ("新插入的数据,上边占了10位,我应该是12");
select * from test;
id | name
-----|------------------------------------
1 | ID为1的老数据
12 | 新插入的数据,上边占了10位,我应该是12
方法二:
(还没时间测试,有问题的话欢迎大家留言)**
这个方法就是要舍弃mysql的自增主键设置,采用另外一张序列表去专门维护主键。
也涉及到一些function啥的
参考:Mysql实现类似Oracle序列
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)
);
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;
-- 使用方法
select currval('seq_name');
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;
-- 使用方法
select nextval('seq_name');
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);