msyql存储过程实现唯一不会重复订单号最佳实践

简介: msyql存储过程实现唯一不会重复订单号最佳实践

在订单系统中订单号不能重复,那么怎么才能高效的生成不会重复的订单号呢?


通过程序生成的订单号为了保证不重复要么就是很长,要么就是一堆没有什么实际意义的长字符串,而且为了保证不重复还得在数据库表字段做唯一约束很不友好,所以通过sql数据库存储过程生成唯一订单号,而且还能有一定规则的方法就很优雅。


第一步需要一个数据库表现导入进去:


CREATE TABLE `generate_serialno`  (

 `id` int(11) NOT NULL,

 `ordervalue` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,

 `ordertime` datetime(0) NULL DEFAULT NULL,

 PRIMARY KEY (`id`) USING BTREE

) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;

第二部创建存储过程sql执行下:


CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_orderNo`(

 IN orderNamePre CHAR(4),

 IN num INT,

 OUT newOrderNo VARCHAR (25)

)

BEGIN

 -- 订单变化的值

 DECLARE orderNameValue INT ;

 -- 更新行数

 DECLARE updateRow INT ;

 -- 当前日期,有可能包含时分秒  

 DECLARE currentTime DATETIME ;

 -- 订单号  

 DECLARE orderCode VARCHAR (64) ;

 DECLARE orderNum INT DEFAULT 5; -- 订单变化的值

 -- 异常处理

 DECLARE CONTINUE HANDLER FOR 1062

 SET currentTime = NOW() ;

 -- 获得订单号

 SELECT

   IFNULL(gs.ordervalue, 0) INTO orderNameValue

 FROM

   generate_serialno gs

 WHERE id = 1 ;

 SET currentTime = NOW() ;

 -- 打开自动提交

 SET autocommit = 1 ;

 IF TRUE -- 如果true插入一条数据

 THEN

 INSERT INTO generate_serialno (id, ordervalue, ordertime)

 VALUES

   (1, 1, currentTime) ;

 END IF ; -- 否则更改订单号

 UPDATE

   generate_serialno obj

 SET

   obj.ordervalue =

   CASE -- 订单变化的值如果今天大于昨天从1开始,否则再原来的基础上加1

     WHEN TO_DAYS(currentTime) > TO_DAYS(obj.ordertime)

     THEN 1

     ELSE orderNameValue + 1

   END,

   obj.ordertime = currentTime

 WHERE ( -- 订单变化的值

     obj.id = 1

     AND obj.ordervalue = orderNameValue

   ) ;

 SET updateRow = ROW_COUNT() ;

 WHILE

   ! updateRow = 1 DO -- 如果更改的行数不等于1

   SELECT -- 获得当前的订单变化值

     IFNULL(gs.ordervalue, 0) INTO orderNameValue

   FROM

     generate_serialno gs

   WHERE id = 1 ;

   UPDATE

     generate_serialno obj

   SET

     obj.ordervalue =

     CASE

       WHEN TO_DAYS(currentTime) > TO_DAYS(obj.ordertime)

       THEN 1

       ELSE orderNameValue + 1

     END,

     obj.ordertime = currentTime

   WHERE (-- 只有订单变化值和id都相等的情况下才能更改,更具行锁的机制

       obj.id = 1

       AND obj.ordervalue = orderNameValue  -- 注意!!!!

     ) ;

   SET updateRow = ROW_COUNT() ;

 END WHILE ;

 IF num = 8

 THEN -- 根据年月日生成订单编号,订单编号形式:前缀+年月日+流水号,如:SH2013011000002    

 SELECT

   CONCAT(   orderNamePre,

     DATE_FORMAT(currentTime, '%Y%m%d'),

     LPAD(orderNameValue, orderNum, '0')

   ) INTO orderCode ;

 ELSEIF num = 14

 THEN -- 根据年月日时分秒生成订单编号,订单编号形式:前缀+年月日时分秒+流水号,如:SH2013011010050700001,个人不推荐使用这种方法生成流水号    

 SELECT

   CONCAT(   orderNamePre,

     DATE_FORMAT(currentTime, '%Y%m%d%H%i%s'),

     LPAD(orderNameValue, orderNum, '0')

   ) INTO orderCode ;

 ELSE -- 根据年月日时分生成订单编号,订单形式:前缀+年月日时分+流水号,如:SH20130110100900005

 SELECT

   CONCAT(   orderNamePre,

     DATE_FORMAT(currentTime, '%Y%m%d%H%i'),

     LPAD(orderNameValue, orderNum, '0')

   ) INTO orderCode ;

 END IF ;

 SELECT

   orderCode ;

END

第三部程序调用存储过程生成唯一订单号:(thinkphp5调用)


        $arr =  Db:: query( "call  generate_orderNo('D',14,@)");

        return  $arr[ '0'][ '0'][ 'orderCode'];

最终效果的


3.jpg

相关文章
|
存储 NoSQL JavaScript
MongoDB存储过程实战:聚合框架、脚本、最佳实践,一文全掌握!
【8月更文挑战第24天】MongoDB是一款备受欢迎的文档型NoSQL数据库,以灵活的数据模型和强大功能著称。尽管其存储过程支持不如传统关系型数据库,本文深入探讨了MongoDB在此方面的最佳实践。包括利用聚合框架处理复杂业务逻辑、封装业务逻辑提高复用性、运用JavaScript脚本实现类似存储过程的功能以及考虑集成其他工具提升数据处理能力。通过示例代码展示如何创建订单处理集合并定义验证规则,虽未直接实现存储过程,但有效地演示了如何借助JavaScript脚本处理业务逻辑,为开发者提供更多实用指导。
248 2
|
SQL 存储 关系型数据库
DB2 存储过程开发最佳实践
转自http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0604changhp/   DB2 存储过程开发最佳实践 常 伟 (changwei@cn.ibm.com), 软件工程师,IBM CSDL 常红 平 (changhp@cn.ibm.com), 软件工程师,IBM CSDL 简介: 本 文以 DB2 开发人员的角度介绍了在 DB2 存储过程开发中需要注意的事项和技巧。
1487 0
|
8月前
|
存储 Java 关系型数据库
java调用mysql存储过程
在 Java 中调用 MySQL 存储过程主要借助 JDBC(Java Database Connectivity)。其核心原理是通过 JDBC 与 MySQL 建立连接,调用存储过程并处理结果。具体步骤包括:加载 JDBC 驱动、建立数据库连接、创建 CallableStatement 对象、设置存储过程参数并执行调用。此过程实现了 Java 程序与 MySQL 数据库的高效交互。
|
7月前
|
存储 关系型数据库 MySQL
【YashanDB知识库】MySQL返回结果集的存储过程的改写方法
本文介绍了将MySQL存储过程改写至YashanDB的解决方案。由于MySQL存储过程可直接返回结果集,而YashanDB需通过返回SYS_REF_CURSOR的函数实现类似功能,因此需要对代码进行转换。示例中展示了如何将MySQL存储过程`proc1`改写为YashanDB函数,并调整JDBC应用代码以适配REF_CURSOR输出参数,从而正确获取查询结果。此方法确保了跨数据库场景下的兼容性与功能性。
|
11月前
|
存储 SQL NoSQL
|
存储 SQL 关系型数据库
MySql数据库---存储过程
MySql数据库---存储过程
151 5
|
存储 关系型数据库 MySQL
MySQL 存储过程返回更新前记录
MySQL 存储过程返回更新前记录
182 3
|
存储 SQL 关系型数据库
MySQL 存储过程错误信息不打印在控制台
MySQL 存储过程错误信息不打印在控制台
224 1
|
存储 关系型数据库 MySQL
Mysql表结构同步存储过程(适用于模版表)
Mysql表结构同步存储过程(适用于模版表)
135 0
|
存储 SQL 关系型数据库
MySQL 创建存储过程注意项
MySQL 创建存储过程注意项
120 0