mysql序列表,自增序列生成合同編號

項目中使用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號

//使用了左填充函數LPAD - 0001
select concat(YEAR(NOW()), ' ', #{contractTplName}, '第C', LPAD(nextval(#{seqName}),4,0), '號')

2020 xxxx第C0001號


1. 創建Sequence管理表 seq_manage
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)
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)
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)
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)
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 ;

測試相關函數:

INSERT INTO seq_manage VALUES ('test', 0, 1);
--添加一個sequence,設置名稱爲'test',初始值爲0,以及每次的自增值爲1。
--如果需要按年份更新,則還需設置year字段初始值,獲取序列時則調用nextvalForYear(name)函數即可

SELECT SETVAL('test', 10);
---設置'test'序列的初始值,這裏設置test的初始值爲10

SELECT CURRVAL('test');  
--查詢'test'序列的當前值

SELECT NEXTVAL('test');  
--查詢'test'序列的下一個值,不會每年重置value值

SELECT nextvalForYear('test');  
--查詢'test'序列的下一個值,每年會更新重置value值
--可以考慮只使用nextvalForYear(name)函數,不用再創建NEXTVAL(name)函數。因爲當序列不需要每年更新時,只需此序列的year字段爲null即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章