一、环境

数据库: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. WPF 在 .NET Core 3.1.19 版本 触摸笔迹偏移问题

    在更新到 .NET 6 发布之前的,在 2021.11.02 的 .NET Core 版本,都会存在此问题.在 WPF 应用里面,如果在高 DPI 下,进行触摸书写,此时的笔迹将会偏移.核心原因是在这 ...

  2. Rancher管理K8s集群(14)

    一.Rancher介绍 1.1 Rancher简介 Rancher 是一个开源的企业级多集群 Kubernetes 管理平台,实现了 Kubernetes 集群在混合云+本地 数据中心的集中部署与管理 ...

  3. webpack调优技巧

    webpack优化主要有三个方面:1.提高构建速度,2.减少打包体积,3.优化用户体验 提高构建速度: 启用多线程 thread-loader 使用thread-loader插件可以启用多线程进行构建 ...

  4. 通俗易懂的生产环境Web应用架构介绍

    前言 看见一篇非常通俗易懂且适合新手阅读的Web应用架构文章,我将其手工翻译了出来,分享给大家. 也可以去阅读英文原文,标题为,贴出链接: https://stephenmann.io/post/wh ...

  5. 通过虚拟机镜像部署zabbix

    前言 由于基础镜像的缘故,zabbix部署过程中很可能出现各种缺少依赖包的情况,如果环境中又无法连接互联网,系统部署会非常麻烦.为此zabbix官方提供了虚拟机镜像,导入后可以直接在平台上拉起虚拟机, ...

  6. Phpstrom开发工具Sftp的使用

  7. kubernetes之包管理器Helm

    安装helm 安装helm客户端 [machangwei@mcwk8s-master ~]$ curl https://raw.githubusercontent.com/kubernetes/hel ...

  8. Java 创建/识别条形码

    项目刚好需要用到就记录一下 -- 依赖 <!-- 条形码生成 --><dependency> <groupId>net.sf.barcode4j</group ...

  9. BigDecimal类的基本使用

    概述 java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的 ...

  10. go强大的垃圾回收机制。

    一.C语言中返回函数中局部变量值和指针(1) 在C语言中,一个函数可以直接返回函数中定义的局部变量,其实在函数返回后,局部变量是被系统自动回收的,因为局部变量是分配在栈空间,那为什么还可以返回局部变量 ...