暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用数据库函数生成有格式的自增ID

谁动了我的BUG 2021-06-01
706



本次案例生成的是(日期+序列)格式的ID,实现的实质其实就是在数据库中使用函数完成固定格式的字符串与序列的拼接,产生新的字符串

本案例以MySQL数据库为例,过程中介绍自定义函数的语法以及MySQL处理字符串和日期的一些函数


案例实现的过程

首先,使用自定义函数模拟序列的产生,由于MySQL数据库不支持序列,所以在实现过程中使用数据表和自定义函数的形式进行实现(PS:oracle数据库是支持序列的。对于序列的产生可以通过SQL语句进行定义)

其次,使用自定义函数完成ID的拼接,在拼接的自定义函数中使用了获取当前时间函数、日期格式化函数、字符串填充函数以及字符串拼接函数

最后创建MySQL的事件,每天对数据表中的序列值进行清零操作


案例实现

首先创建序列记录表

由于考虑到MySQL的关键字以及保留字的问题,所以表命名为t_sequence,表中s_name记录的是序列的名称,s_value字段记录的是序列的当前值,s_next记录的是序列的自增步长


表建好之后创建获取序列的函数(next_trans_num)
    CREATE FUNCTION next_trans_num(seq_name VARCHAR(255)) RETURNS INT
    BEGIN
    UPDATE t_sequence SET s_value =LAST_INSERT_ID(s_value+s_next) WHERE s_name = seq_name;
      RETURN LAST_INSERT_ID();
    END


    在自定义函数中使用了系统提供的LAST_INSERT_ID函数,该函数在这里可以理解为获取该表中最后更新的值(此处只是辅助理解,建议在使用此函数生成序列时,放弃MySQL的整型主键自增序列的使用,即:在这个库中最好不要使用自增型int主键)

    函数执行完成之后继续自定义拼接函数(get_trans_num)

     

      CREATE FUNCTION get_trans_num() RETURNS VARCHAR(24)
      BEGIN
        DECLARE getval VARCHAR(24);
        SET getval = (SELECT CONCAT (DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(next_trans_num('trans_no'),10,'0')));
      RETURN getval;
      END

      此函数中第一行是创建字符串变量长度是24个字符变量名叫getval,第二行是对变量进行赋值,在赋值过程中使用CONCAT函数对两个字符串进行拼接。

      首先是DATE_FORMAT函数对NOW()函数获取的当前时间进行格式化并返回字符串格式的值,DATE_FORMAT中的第二个函数是日期的格式化格式,其中字母对应的分别是年月日时分秒(可以根据需求进行取舍)

      其次是使用LPAD对序列的值进行格式化。函数中第一个参数是需要格式化的值;第二个参数是输出字符串的长度,第三个参数是空缺部分的填充字符。(PS:第一个参数的值会被拼接在输出字符串的尾部)

      函数执行之后,即完成操作。


      总结

      上述案例可改进的空间很大,get_trans_num函数可以通过声明形参的形式将序列的名称(即s_name的值)在调用的过程中传递进来实现动态的多序列获取等等

      最后自定义函数的使用方法

      测试函数是否可用

        SELECT get_trans_num();

        插入时调用函数

          INSERT INTO users (user_id,user_name,user_pass) VALUES (get_trans_num(),'zhangsan','123456');

          注意ID的类型应该改为varchar

          文章转载自谁动了我的BUG,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论