MySql存储过程循环的使用分析详解
作者:生命猿于运动? 发布时间:2024-01-19 05:13:48
标签:MySql,存储,循环
简介
每一门数据库语言语法都基本相似,但是对于他们各自的一些特性(函数、存储过程等)的用法就不大相同了,就好比Oracle
与Mysql
存储过程写起来就很多不同的地方,在这里主要是跟大家分享一下MySql
存储过程中使用游标循环的处理方法。
场景描述
我们举一个简单的场景,首先我们可能会有这样一种情况,考试成绩表(t_achievement
)有一堆的sql脚本处理,需要依赖另一个学生表(t_student
)数据对部分学生做考试成绩汇总记录到成绩汇总表(t_achievement_report
)。
解决方案
有一种方式就是通过代码优先将要汇总的学生表数据获取出来,然后按成绩汇总流程逐个将学生信息数据传递到成绩汇总业务代码进行处理。
另一种方式也是我们今天的主题,那就是通过存储过程的方式去做。
案例
建表语句:
-- 学生信息表
DROP TABLE IF EXISTS t_student;
CREATE TABLE `t_student` (
`id` BIGINT(12) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` VARCHAR(10) NOT NULL COMMENT '学号',
`name` VARCHAR(20) NOT NULL COMMENT '姓名',
`age` INT(2) NOT NULL COMMENT '年龄',
`gender` CHAR(1) NOT NULL COMMENT '性别(M:男,F:女)',
PRIMARY KEY (`id`),
UNIQUE KEY UK_STUDENT (`code`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- 学生成绩表
DROP TABLE IF EXISTS t_achievement;
CREATE TABLE `t_achievement` (
`id` BIGINT(12) NOT NULL AUTO_INCREMENT COMMENT '主键',
`year` INT(4) NOT NULL COMMENT '学年',
`subject` CHAR(2) NOT NULL COMMENT '科目(01:语文,02:数学,03:英语)',
`score` INT(3) NOT NULL COMMENT '得分',
`student_id` BIGINT(12) NOT NULL COMMENT '所属学生id',
PRIMARY KEY (`id`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- 成绩汇总表
DROP TABLE IF EXISTS t_achievement_report;
CREATE TABLE `t_achievement_report` (
`id` BIGINT(12) NOT NULL AUTO_INCREMENT COMMENT '主键',
`student_id` BIGINT(12) NOT NULL COMMENT '学生id',
`year` INT(4) NOT NULL COMMENT '学年',
`total_score` INT(4) NOT NULL COMMENT '总分',
`avg_score` DECIMAL(4,2) NOT NULL COMMENT '平均分',
PRIMARY KEY (`id`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
初始化数据:
INSERT INTO t_student(id, CODE, NAME, age, gender) VALUES
(1, '2022010101', '小张', 18, 'M'),
(2, '2022010102', '小李', 18, 'F'),
(3, '2022010103', '小明', 18, 'M');
INSERT INTO t_achievement(YEAR, SUBJECT, score, student_id) VALUES
(2022, '01', 80, 1),
(2022, '02', 85, 1),
(2022, '03', 90, 1),
(2022, '01', 60, 2),
(2022, '02', 90, 2),
(2022, '03', 98, 2),
(2022, '01', 75, 3),
(2022, '02', 100, 3),
(2022, '03', 85, 3);
存储过程:
在这里主要以上面的场景为例,使用存储过程循环去处理数据。写一个存储过程,将以上数据每个学生的成绩进行汇总。
-- 如果存储过程存在,先删除存储过程
DROP PROCEDURE IF EXISTS statistics_achievement;
DELIMITER $$
-- 定义存储过程
CREATE PROCEDURE statistics_achievement()
BEGIN
-- 定义变量记录循环处理是否完成
DECLARE done BOOLEAN DEFAULT FALSE;
-- 定义变量传递学生id
DECLARE studentid BIGINT(12);
-- 定义游标
DECLARE cursor_student CURSOR FOR SELECT id FROM t_student;
-- 定义CONTINUE HANDLER,当循环结束时 done=true
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=TRUE;
-- 打开游标
OPEN cursor_student;
-- 重复遍历
REPEAT
-- 每次读取一次游标
FETCH cursor_student INTO studentid;
-- 计算总分、平均分插入汇总表
INSERT INTO t_achievement_report(student_id, `YEAR`, total_score, avg_score)
SELECT studentid, `YEAR`, SUM(score), ROUND(SUM(score) / 3, 2) FROM t_achievement t1 WHERE student_id = studentid AND NOT EXISTS(
SELECT 1 FROM t_achievement_report t2 WHERE student_id = studentid AND t1.year = t2.year
) GROUP BY `YEAR`;
-- 结束循环,意思是等到done=true时,结束循环REPEAT
UNTIL done END REPEAT;
-- 查询结果,仅会展示查出的最后一条
SELECT studentid;
-- 关闭游标
CLOSE cursor_student;
END$$
DELIMITER ;
-- 执行存储过程
CALL statistics_achievement();
执行结果,返回查询结果3,即最后一条学生记录id
来源:https://juejin.cn/post/7110205925712986148


猜你喜欢
- 很类似java的properties文件xml文件db_config.ini[baseconf]host=127.0.0.1port=330
- 使用本文给出的方法就可以制作出一个简单的rss阅读器了。用xmldom方法打开xml文件,如果是本地的没有问题,就是用Server.MapP
- 1. 引言现在有一个需求是从一个单词表中每次随机选取三个单词。这个表的建表语句和如下所示:mysql> Create table
- 直接在线安装1、File->Settings->Plugins->Install JetBrains Plugins2、点
- 目录1. 前言2. 实战一下2-1 进入虚拟环境,创建一个项目及 App2-2 创建模板目录并配置 set
- 本文详细介绍使用 PHP 动态构建 PDF 文件的整个过程。使用免费 PDF 库 (FPDF) 或 PDFLib-Lite 等开源工具进行实
- SQL(结构化查询语言)是一种通用数据库查询语言。SQL具有数据定义、数据操作和数据控制功能,可以完成数据库的全部工作。SQL语言使用时只需
- 前言Go 1.3 的sync包中加入一个新特性:Pool。这个类设计的目的是用来保存和复用临时对象,以减少内存分配,降低CG压力。type
- SQL语句先前写的时候,很容易把一些特殊的用法忘记,我特此整理了一下SQL语句操作,方便自己写SQL时方便一点,想贴上来,一起看看,同时希望
- 1 问题在使用pyecharts绘制可视化地图信息时候,默认出现的图像是带有圆点标记,比如官网代码运行输出如下:2 问题解决方式一: sho
- php输出全部gb2312编码内的汉字,$area表示分区,$pos表示分区内所在位置。<?php$fp = fopen('t
- Spyder本来还用得好好的,能正常使用,后来再关闭打开时,出现下面的蜘蛛网界面后,就无法显示操作界面了:后来在网上搜索了多种方法,甚至还将
- 前言:vue-router的切换不同于传统的页面的切换。路由之间的切换,其实就是组件之间的切换,不是真正的页面切换。这也会导致一个问题,就是
- 1. AdaBoost 算法简介Boosting是机器学习的三大框架之一,其特点是,训练过程中的诸多弱模型,彼此之间有着强依赖关系。Boos
- 1. filter1.1 把一个序列中的空字符串删掉例如将[‘A’, ‘&
- 1.什么是Blazor? 有什么优势?ASP.NET Core Blazor 简介Blazor 是一个使用 Blazor 生成交互式客户端
- 在pandas中创建category类型数据的几种方法之详细攻略 T1、直接创建 category类型数据可知,在category
- 斜角导航条看上去立体感比较强,但实现起来比较麻烦;这是前几天写的一个测试代码,实现时,本来想用简单的图片加负数来实现;但GIF图片对半透明的
- <html xmlns="http://www.w3.org/1999/xhtml"><head>
- 最近在上《自然语言处理》这门选修课,为了完成上机作业也是很认真了,这次是为了实现语角色标注任务,于是就入了这个坑,让我们来(快乐地 )解决出