项目中使用mysql数据库,需要使用自增序列号生成合同编号,编号按年份每年更新,且根据合同模板不同需使用多个自增序列。为了考虑拓展性,也方便其他业务使用序列,使用了序列表进行集中管理,使用函数操作序列。
解决思路
currval(name)函数获取当前序列值。
nextval(name)函数获取下一个序列值,即先自增value更新后再调用currval(name)。
nextvalForYear(name)函数适用于按年份每年更新重置value值的场景。
setval(name,value)函数根据传入的参数手动重置value。
- 附: 合同编号的字符串拼接函数
CONCAT(str1,str2,…):字符串拼接函数
LPAD(str,len,padstr):字符串左填充函数
RPAD(str,len,padstr):字符串右填充函数
例: 拼接格式 - 2020 xxxx第C0001号
1 2
| //使用了左填充函数LPAD - 0001 select concat(YEAR(NOW()), ' ', #{contractTplName}, '第C', LPAD(nextval(#{seqName}),4,0), '号')
|

1. 创建Sequence管理表 seq_manage
1 2 3 4 5 6 7 8
| DROP TABLE IF EXISTS seq_manage; CREATE TABLE seq_manage ( seq_name VARCHAR(50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 1, year INT(4), PRIMARY KEY (seq_name) ) ENGINE=InnoDB;
|
2. 取当前值 currval(name)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| DROP FUNCTION IF EXISTS currval; DELIMITER $ CREATE FUNCTION currval (name VARCHAR(50)) RETURNS INTEGER LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE value INTEGER; SET value = 0; SELECT current_value INTO value FROM seq_manage WHERE seq_name = name; RETURN value; END $ DELIMITER ;
|
3. 取下一个值 nextval(name)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| DROP FUNCTION IF EXISTS nextval; DELIMITER $ CREATE FUNCTION nextval (name VARCHAR(50)) RETURNS INTEGER LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN UPDATE seq_manage SET current_value = current_value + increment WHERE seq_name = name; RETURN currval(name); END $ DELIMITER ;
|
4. 取下一个值 nextvalForYear(name)(按年份每年自动重置value)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| DROP FUNCTION IF EXISTS nextvalForYear; DELIMITER $ CREATE FUNCTION nextvalForYear (name VARCHAR(50)) RETURNS INTEGER LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN set @year = (select year from seq_manage WHERE seq_name = name);
IF YEAR(NOW()) > @year THEN UPDATE seq_manage SET current_value = 1, year = YEAR(NOW()) WHERE seq_name = name; RETURN currval(name); ELSE UPDATE seq_manage SET current_value = current_value + increment WHERE seq_name = name; RETURN currval(name);
END IF; END $ DELIMITER ;
|
5. 更新当前值 setval(name,value)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| DROP FUNCTION IF EXISTS setval; DELIMITER $ CREATE FUNCTION setval (name VARCHAR(50), value INTEGER) RETURNS INTEGER LANGUAGE SQL DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN UPDATE seq_manage SET current_value = value WHERE seq_name = name; RETURN currval(name); END $ DELIMITER ;
|
测试相关函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| INSERT INTO seq_manage VALUES ('test', 0, 1);
SELECT SETVAL('test', 10);
SELECT CURRVAL('test');
SELECT NEXTVAL('test');
SELECT nextvalForYear('test');
|