MYSQL 存储过程 生成唯一流水号

采用mysql存储过程生成唯一流水号功能,支持并发。

项目中需要生产出库单的流水号,之前用了很多方法都无法解决并发时流水号重复的问题。

直到看见csdn上《关于生成并发唯一性流水号的解决方案》这篇文章,茅塞顿开,作者写的太好了。

尤其是使用update来进行锁定表内容,大大降低了代码难度。因为项目采用的是mysql数据库,因此采用mysql的存储过程重新写了一边。


创建数据库: 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;




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);      来作为中转解决问题。

 


                
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值