MYSQL 存储过程 生成唯一流水号
2016-11-14 22:23
477 查看
采用mysql存储过程生成唯一流水号功能,支持并发。
项目中需要生产出库单的流水号,之前用了很多方法都无法解决并发时流水号重复的问题。
直到看见csdn上《关于生成并发唯一性流水号的解决方案》这篇文章,茅塞顿开,作者写的太好了。
尤其是使用update来进行锁定表内容,大大降低了代码难度。因为项目采用的是mysql数据库,因此采用mysql的存储过程重新写了一边。
1 创建数据库: sys_sno
2
因为实际项目中流水号是按照月份来生成的,因此使用
特别注意:
2016年11月14日时 '1611140000001'
SUBSTRING(tsValue,1,6) 后的值与 DATE_FORMAT(NOW(),'%y%m') 相等
SUBSTRING(tsValue,1,4) 后的值与 DATE_FORMAT(NOW(),'%y') 不相等!!
原因是1614强制赋值给datetime类型时 其不是一个有效的datetime值 因此 与 DATE_FORMAT(NOW(),'%y') 不同。
所以项目中使用
DECLARE tdToday VARCHAR(20);
DECLARE nowdate VARCHAR(20); 来作为中转解决问题。
项目中需要生产出库单的流水号,之前用了很多方法都无法解决并发时流水号重复的问题。
直到看见csdn上《关于生成并发唯一性流水号的解决方案》这篇文章,茅塞顿开,作者写的太好了。
尤其是使用update来进行锁定表内容,大大降低了代码难度。因为项目采用的是mysql数据库,因此采用mysql的存储过程重新写了一边。
1 创建数据库: sys_sno
CREATE TABLE `sys_sno` ( `sCode` varchar(50) DEFAULT NULL, `sName` varchar(100) DEFAULT NULL, `sQz` varchar(50) DEFAULT NULL, `sValue` varchar(80) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2
DELIMITER $$ USE `hrpdb`$$ DROP PROCEDURE IF EXISTS `GetSerialNo`$$ CREATE DEFINER=`root`@`localhost` PROCEDURE `GetSerialNo`(IN tsCode VARCHAR(50),OUT result VARCHAR(200) ) BEGIN DECLARE tsValue VARCHAR(50); DECLARE tdToday VARCHAR(20); DECLARE nowdate VARCHAR(20); DECLARE tsQZ VARCHAR(50); DECLARE t_error INTEGER DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; START TRANSACTION; UPDATE sys_sno SET sValue=sValue WHERE sCode=tsCode; SELECT sValue INTO tsValue FROM sys_sno WHERE sCode=tsCode; SELECT sQz INTO tsQZ FROM sys_sno WHERE sCode=tsCode ; -- 因子表中没有记录,插入初始值 IF tsValue IS NULL THEN SELECT CONCAT(DATE_FORMAT(NOW(),'%y%m'),'0000001') INTO tsValue; UPDATE sys_sno SET sValue=tsValue WHERE sCode=tsCode ; SELECT CONCAT(tsQZ,tsValue) INTO result; ELSE SELECT SUBSTRING(tsValue,1,4) INTO tdToday; SELECT CONVERT(DATE_FORMAT(NOW(),'%y%m'),SIGNED) INTO nowdate; IF tdToday = nowdate THEN SET tsValue=CONVERT(tsValue,SIGNED) + 1; ELSE SELECT CONCAT(DATE_FORMAT(NOW(),'%y%m') ,'0000001') INTO tsValue ; END IF; UPDATE sys_sno SET sValue =tsValue WHERE sCode=tsCode; SELECT CONCAT(tsQZ,tsValue) INTO result; END IF; IF t_error =1 THEN ROLLBACK; SET result = 'Error'; ELSE COMMIT; END IF; SELECT result ; END$$ DELIMITER ;
因为实际项目中流水号是按照月份来生成的,因此使用
DATE_FORMAT(NOW(),'%y%m')
特别注意:
2016年11月14日时 '1611140000001'
SUBSTRING(tsValue,1,6) 后的值与 DATE_FORMAT(NOW(),'%y%m') 相等
SUBSTRING(tsValue,1,4) 后的值与 DATE_FORMAT(NOW(),'%y') 不相等!!
原因是1614强制赋值给datetime类型时 其不是一个有效的datetime值 因此 与 DATE_FORMAT(NOW(),'%y') 不同。
所以项目中使用
DECLARE tdToday VARCHAR(20);
DECLARE nowdate VARCHAR(20); 来作为中转解决问题。
相关文章推荐
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mybatis+mysql 使用存储过程生成流水号的实现代码
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- mysql 生成流水号 存储过程 订单编号
- 高并发下生成订单唯一流水号的方法
- sqlSever 存储过程 中 创建 事务(增删改操作),唯一的主键自动生成 (格式:自定义字母+时间+五位数字,例如:S2014103010001)