MYSQL8存储过程生成日历表以及异常处理
一、环境
数据库: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存储过程生成日历表以及异常处理的更多相关文章
- SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息
原文:SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2 ...
- Sqlserver存储过程生成日期维度
话不多说,之前已经有一篇日志是利用oracle的存储过程生成日期维度表,接下来我们就用sqlserver来实现这个操作,如下面的步骤所示 1:创建日期维度表(Dim_time) USE [DW] GO ...
- SQL Server 存储过程生成流水号
SQL Server利用存储过程生成流水号 USE BiddingConfig SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON GO -- =========== ...
- 用SQL存储过程生成唯一单据号
用SQL存储过程生成唯一单据号 在一些系统中,经理要生成单据号,为了不使多台客户端生成的单据号重复,一般要在服务端生成这种流水号,本文是在数据库中生成流水号,并且可以生成多种类型的单据号(比如 ...
- MySql生成日历表
mysql使用存储过程,创建日历表: 准备日历表: CREATE TABLE `m_dim_day` ( `ID` ) NOT NULL AUTO_INCREMENT, `DAY_ID` ) DEFA ...
- SQL Server 存储过程生成insert语句
你肯定有过这样的烦恼,同样的表,不同的数据库,加入你不能执行select insert 那么你肯定需要一条这样的存储过程,之需要传入表明,就会给你生成数据的插入语句. 当然数据表数量太大,你将最好用 ...
- Mysql存储过程(四)——异常处理
http://blog.csdn.net/crazylaa/article/details/5368421 有时候,不希望存储过程抛出错误中止执行,而是希望返回一个错误码. MySQL 支持异常处理, ...
- SQL存储过程生成顺序编码
一.第一种方式 USE [WJKC]GO/****** Object: StoredProcedure [dbo].[Address_GetCode1] Script Date: 2016/3 ...
- SQL SERVER存储过程生成字母+数字的编码
公司内设备管理系统中设备建账功能,功能目的是对新进设备进行记录并入库.其中设备编号一项定义为自己修改(查看之前的设备号,取一个不重复的值来填写),感觉特别麻烦!用存储过程自动生成编码岂不是更效率. 需 ...
- Oracle存储过程生成日期维度
在数据仓库的创建过程中,往往需要创建日期维度来为以后的数据分析来服务. 方面从多个日期角度: 如:年-月-日,年-季度-月-日,年-周-日 创建表的脚本如下(存储过程的创建过程中有一步操作是向time ...
随机推荐
- 建立成功平台工程的关键:自助式 IaC
从技术上讲,云一直都是自助式服务,但由于其在实践中的复杂性,许多开发人员并不喜欢.随着公司采用现代架构(云原生.无服务器等)和新的提供商(多云.SaaS 应用程序),以及云提供商发布更多服务,云变得更 ...
- 《最新出炉》系列入门篇-Python+Playwright自动化测试-44-鼠标操作-上篇
1.简介 前边文章中已经讲解过鼠标的拖拽操作,今天宏哥在这里对其的其他操作进行一个详细地介绍和讲解,然后对其中的一些比较常见的.重要的操作单独拿出来进行详细的介绍和讲解. 2.鼠标操作语法 鼠标操作介 ...
- Asynq 实现 Go 异步任务处理
目录 Asynq 实现 Go 异步任务处理 一.概述 二.快速开始 1. 准备工作 2. 安装asynq软件包 3. 创建项目asynq_task 2. Redis连接项 4. Task任务 5. 编 ...
- python Requests 库的使用
目录 1. 介绍 2. 安装 3. 基本请求 3.1 get请求 3.2 post请求 3.3 自定义请求头部 3.4 设置超时时间 3.5 代理访问 3.6 session自动保存cookies 3 ...
- Elasticsdump 数据导入/导出
目录 一.安装过程 安装NODE 通过npm安装elasticdump 二.数据导出 实操一 实操二 实操三 三.文件导入 一.安装过程 当前工具主要是用来对ES中的数据进行数据导入/导出,以及对数据 ...
- DNS(3) -- dns常用命令-rndc-dig-host-nslookup
目录 1 bind自带客户端命令 1.1 rndc命令 1.2 检查配置文件语法 2 客户端测试命令 2.1 dig命令 2.2 host命令 2.3 nslookup命令 1 bind自带客户端命令 ...
- Scala集合flatten操作
一层嵌套,但是flatten的要求需要List内部类型都一样, 例如都为List scala> List(List(1), List(2), List(3)).flatten res4: Lis ...
- C#.Net筑基-模式匹配汇总
01.模式匹配概述 从C#7开始支持的 模式匹配 语法(糖,挺甜),可非常灵活的对数据进行条件匹配和提取,经过多个版本的完善,已经非常强大了. C# 支持多种模式,包括声明.类型.常量.关系.属性.列 ...
- Linux下mv和cp命令的区别
1.功能上的区别 mv:用户可以使用mv为文件或目录重命名或将文件由一个目录移入另一个目录中. cp: cp的功能是将给出的文件或目录拷贝到另一文件或目录中. 2.inode上的区别(inod ...
- .net Mvc5Webapi接口接收参数为null的一种情况分享
同样的前后端项目,其他接口用post接收自定义对象形式的参数,是能成功接收的.在这个前提下,出现某个接口接收的参数为null或值全是默认值,可能的原因是这样: 前端定义的参数的字段比后台定义的dto对 ...