一、环境

数据库:mysql8.0.25 社区版

操作系统:windows 11

------------------------------------

二、创建日历表

CREATE TABLE `sys_calendar` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`day_date` datetime DEFAULT NULL,
`year_num` int DEFAULT NULL,
`month_num` int DEFAULT NULL,
`day_num` int DEFAULT NULL,
`day_str` varchar(10) DEFAULT NULL,
`day_int` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

三、创建存储过程

DROP PROCEDURE IF EXISTS sp_createcalendar;
DELIMITER $$ CREATE PROCEDURE `spring`.`sp_createcalendar`(IN pstartyear INT ,IN pendyear INT)
BEGIN
DECLARE v_msg VARCHAR(100) DEFAULT 'good'; DECLARE v_year INT DEFAULT 0;
DECLARE v_month INT DEFAULT 0;
DECLARE v_day INT DEFAULT 0;
DECLARE v_day_dt DATETIME;
DECLARE v_day_str VARCHAR(10);
DECLARE v_day_int INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLSTATE '22007' SET v_msg='error';
TRUNCATE TABLE sys_calendar;
SET v_year=pstartyear;
WHILE v_year<=pendyear DO
SET v_month=1;
WHILE v_month<=12 DO
SET v_day=1;
WHILE v_day<=31 DO
SET v_day_int=V_YEAR*10000+v_month*100+v_day;
SET v_day_dt= STR_TO_DATE(v_day_int,'%Y%m%d');
IF (v_day_dt IS NOT NULL) THEN
SET v_day_str=DATE_FORMAT(v_day_dt,'%Y/%m/%d');
INSERT INTO sys_calendar (
day_date,
year_num,
month_num,
day_num,
day_str,
day_int
)
VALUES
(
v_day_dt,
v_year,
v_month,
v_day,
v_day_str,
v_day_int
);
END IF;
IF @v_msg='error' THEN
SET v_day=32; -- 跳出循环
END IF;
SET v_day=v_day+1;
END WHILE;
SET v_month=v_month+1;
END WHILE;
SET v_year=v_year+1;
END WHILE; END$$ DELIMITER ;

这个过程写了好一会,大概快一个小时,时间都浪费查资料解决几个问题:

1.如何定义变量, 比过去好了

2.如何赋值和使用,比过去好了,不要再带@。要带@也可以,主要是为了向下兼容。

3.如何处理异常,和过去一样垃圾,需要实现定义异常处理,并定义异常处理的语句后面不能有declare。

稍微可以重点说的是:异常处理之后跳出本循环

 IF @v_msg='error' THEN
SET v_day=32; -- 跳出循环
END IF;

以上的语句的意思是:

判断异常变量是否为'error',如果是则设置循环变量为不满足循环条件,则会跳出本循环。

变量v_msg的值,是异常处理定义语句执行后设置的。

DECLARE CONTINUE HANDLER FOR SQLSTATE '22007' SET v_msg='error';

上面一个语句的意思是:发生异常(错误状态为22007),则把变量设置为'error'。

四、执行存储过程

4.1生成日表

CALL sp_createcalendar(2010,2030);

查询看看结果:

SELECT * FROM sys_calendar;
SELECT COUNT(*),year_num FROM sys_calendar GROUP BY year_num;

4.2生成年表月表

CREATE TABLE sys_cal_year(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
year_num INT UNSIGNED UNIQUE NOT NULL,
year_str VARCHAR(4) NOT NULL,
PRIMARY KEY(id)
) COMMENT '日历年份表';
INSERT INTO sys_cal_year(year_num,year_str)
SELECT year_num,year_num AS year_str FROM (
SELECT DISTINCT year_num FROM sys_calendar
) vy; --
CREATE TABLE sys_cal_yearmonth(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
yearmonth_int INT UNSIGNED UNIQUE NOT NULL,
yearmonth_str VARCHAR(6) NOT NULL,
PRIMARY KEY(id)
) COMMENT '日历年月表'; INSERT INTO sys_cal_yearmonth(
yearmonth_int,
yearmonth_str)
SELECT yearmonth_num,yearmonth_num FROM (
SELECT DISTINCT year_num*100+month_num AS yearmonth_num FROM sys_calendar
)vym;

五、获取异常状态信息(SQLSTATE)

mysql有意思的是sqlstate和出现异常的提示的SQLCODE不是一个东西,徒增用户麻烦。

如果不知道异常代码是啥,那么好办,有一个办法(也许有更好的)。

以下代码参考:Mysql 获取存储过程中的异常信息 - 一叶扁舟,乘风破浪 - 博客园 (cnblogs.com)

DROP PROCEDURE IF EXISTS sp_exception;
DELIMITER $$ CREATE PROCEDURE `spring`.`sp_exception`()
BEGIN
DECLARE code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE result TEXT;
declare v_day_dt datetime;
-- 声明异常处理
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
-- 获取异常code,异常信息
GET DIAGNOSTICS CONDITION 1
code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END; SET v_day_dt= STR_TO_DATE(20100229,'%Y%m%d');
INSERT INTO sys_calendar (
day_date,
year_num,
month_num,
day_num,
day_str,
day_int
)
VALUES
(v_day_dt,
2010,
2,
29,
'2020/02/29',
20200229);
select msg,code; END$$ DELIMITER ;

执行以上过程,返回结果:

六、小结

1.mysql的存储过程比较垃圾,无论循环控制,异常处理,执行效率,事务控制。虽然已经比过去的版本好了一些些!

2.如果有啥好处,就是可以写一些小函数,当不想写java等高级语言的时候,有个替代选项。

3.希望它赶紧升级,靠向oracle存储过程--不过难度可能有点大。

MYSQL8存储过程生成日历表以及异常处理的更多相关文章

  1. SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息

    原文:SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2 ...

  2. Sqlserver存储过程生成日期维度

    话不多说,之前已经有一篇日志是利用oracle的存储过程生成日期维度表,接下来我们就用sqlserver来实现这个操作,如下面的步骤所示 1:创建日期维度表(Dim_time) USE [DW] GO ...

  3. SQL Server 存储过程生成流水号

    SQL Server利用存储过程生成流水号 USE BiddingConfig SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON GO -- =========== ...

  4. 用SQL存储过程生成唯一单据号

    用SQL存储过程生成唯一单据号     在一些系统中,经理要生成单据号,为了不使多台客户端生成的单据号重复,一般要在服务端生成这种流水号,本文是在数据库中生成流水号,并且可以生成多种类型的单据号(比如 ...

  5. MySql生成日历表

    mysql使用存储过程,创建日历表: 准备日历表: CREATE TABLE `m_dim_day` ( `ID` ) NOT NULL AUTO_INCREMENT, `DAY_ID` ) DEFA ...

  6. SQL Server 存储过程生成insert语句

    你肯定有过这样的烦恼,同样的表,不同的数据库,加入你不能执行select  insert 那么你肯定需要一条这样的存储过程,之需要传入表明,就会给你生成数据的插入语句. 当然数据表数量太大,你将最好用 ...

  7. Mysql存储过程(四)——异常处理

    http://blog.csdn.net/crazylaa/article/details/5368421 有时候,不希望存储过程抛出错误中止执行,而是希望返回一个错误码. MySQL 支持异常处理, ...

  8. SQL存储过程生成顺序编码

    一.第一种方式 USE [WJKC]GO/****** Object:  StoredProcedure [dbo].[Address_GetCode1]    Script Date: 2016/3 ...

  9. SQL SERVER存储过程生成字母+数字的编码

    公司内设备管理系统中设备建账功能,功能目的是对新进设备进行记录并入库.其中设备编号一项定义为自己修改(查看之前的设备号,取一个不重复的值来填写),感觉特别麻烦!用存储过程自动生成编码岂不是更效率. 需 ...

  10. Oracle存储过程生成日期维度

    在数据仓库的创建过程中,往往需要创建日期维度来为以后的数据分析来服务. 方面从多个日期角度: 如:年-月-日,年-季度-月-日,年-周-日 创建表的脚本如下(存储过程的创建过程中有一步操作是向time ...

随机推荐

  1. [FAQ] Argument 3 passed to Lcobucci\JWT\Signer\Hmac::doVerify() must be an instance of Lcobucci\JWT\Signer\Key, null given

    出现这个错误,说明没有找到 key,在使用 laravel-jwt 之前需要生成加密 key,使用: $ php artisan jwt:secret Link:https://www.cnblogs ...

  2. 习题8 #第8章 Verilog有限状态机设计-1 #Verilog #Quartus #modelsim

    1. 设计一个"111"串行数据检测器.要求是:当检测到连续3个或3个以上的"1"时输出为1,其他输入情况下输出为0. (1)思路分析:参照本章前文的范例,如第 ...

  3. 11个Python循环技巧

    本文分享自华为云社区<Python中的循环技巧指南>,作者:柠檬味拥抱. 当我们处理数据时,有时候需要创建多个列表以存储不同类型或不同条件下的数据.在Python中,我们可以利用循环来快速 ...

  4. Oracle和达梦:根据外键名字查询表名

    根据外键名字查询表名 select * from user_cons_columns cl where cl.constraint_name = '外键名';

  5. 使用WebSocket实现实时多人答题对战游戏

    前言 前两章教程,我们使用WebSocket的基础特性打造了一个小小聊天室,并在第二章对其进行了集群化改造. 系列教程回顾: [WebSocket]第一章:手把手搭建WebSocket多人在线聊天室( ...

  6. 🔥 PyTorch神操作:一图秒懂Tensor变形记!

    亲爱的码农小伙伴们,你们是否还在为Tensor的各种变换头大如斗?别怕,今天给大家送上一张超实用的PyTorch变换秘籍图,让你的Tensor操作如行云流水,CPU和GPU之间的切换如穿梭自如! GP ...

  7. 【转载】只有.dbf数据文件进行数据库恢复

    此篇文章为转载,来自 " ITPUB博客 " ,链接:http://blog.itpub.net/26015009/viewspace-714742/ 个人mark下,在之后dbf ...

  8. 06 curl 操作elasticsearch的CRUD

    目录 查看健康状态 查询当前es集群中所有的indices 创建索引并配置: 创建索引 删除索引 获取mapping 创建mapping 添加字段 插入记录 检索 修改 删除 中文文档: https: ...

  9. LocalDateTime 时间偏移量的处理

    一.代码处理块 // 当前系统时间两年后的时间 LocalDateTime expirationTime = LocalDateTimeUtil.offset(LocalDateTime.now(), ...

  10. MySQL优化方向

    MySQL优化手段 数据库设计层面 范式设计 减少数据冗余 提高数据一致性 索引策略 选择合适的索引类型 (BTREE, HASH) 覆盖索引 索引选择性 表结构优化 使用合适的数据类型 避免使用NU ...