MySQL-SQL存储过程/触发器详解(下)

news2024/11/15 15:44:51

♥️作者:小刘在C站

♥️个人主页: 小刘主页 

♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!

♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术

♥️小刘私信可以随便问,只要会绝不吝啬,感谢CSDN让你我相遇!

前言

上章讲到MySQL-SQL存储过程/触发器详解(上)本章继续

目录

1.4 if

1). 介绍

2). 案例

1.4.1参数

1). 介绍

 用法:

2). 案例一

3). 案例二

1.4.2 case

1). 介绍

语法2:

2). 案例

1.4.3while

1). 介绍

2). 案例

1.4.4repeat

1). 介绍

2). 案例

1.4.5 loop

1). 介绍

2). 案例一

3). 案例二

1.4.6

1). 介绍

A. 声明游标

B. 打开游标

C. 获取游标记录

D. 关闭游标

2). 案例

1.4.7条件处理程序

1). 介绍

2). 案例


1.4 if

1). 介绍

if 用于做条件判断,具体的语法结构为:
IF 条件1 THEN
.....
ELSEIF 条件2 THEN -- 可选
.....
ELSE -- 可选
.....
END IF;
if 条件判断的结构中, ELSE IF 结构可以有多个,也可以没有。 ELSE 结构可以有,也可以没有。

2). 案例

根据定义的分数 score 变量,判定当前分数对应的分数等级。
score >= 85 分,等级为优秀。
score >= 60 分 且 score < 85 分,等级为及格。
score < 60 分,等级为不及格。
create procedure p3()
begin
declare score int default 58;
declare result varchar(10);
if score >= 85 then
set result := '优秀';
elseif score >= 60 then
set result := '及格';
else
set result := '不及格';
end if;
select result;
end;
call p3(); 
上述的需求我们虽然已经实现了,但是也存在一些问题,比如: score 分数我们是在存储过程中定义死的,而且最终计算出来的分数等级,我们也仅仅是最终查询展示出来而已。
那么我们能不能,把 score 分数动态的传递进来,计算出来的分数等级是否可以作为返回值返回呢?答案是肯定的,我们可以通过接下来所讲解的 参数 来解决上述的问题。 、

1.4.1参数

1). 介绍

参数的类型,主要分为以下三种: IN OUT INOUT 。 具体的含义如下:

 用法:

CREATE PROCEDURE 存储过程名称 ([ IN/OUT/INOUT 参数名 参数类型 ])
BEGIN
-- SQL语句
END ;

2). 案例一

根据传入参数 score ,判定当前分数对应的分数等级,并返回。
score >= 85 分,等级为优秀。
score >= 60 分 且 score < 85 分,等级为及格。
score < 60 分,等级为不及格。
create procedure p4(in score int, out result varchar(10))
begin
if score >= 85 then
set result := '优秀';
elseif score >= 60 then
set result := '及格';
else
set result := '不及格';
end if;
end;
-- 定义用户变量 @result来接收返回的数据, 用户变量可以不用声明
call p4(18, @result);
select @result;

3). 案例二

将传入的200分制的分数,进行换算,换算成百分制,然后返回。
create procedure p5(inout score double)
begin
set score := score * 0.5;
end;
set @score = 198;
call p5(@score);
select @score;

1.4.2 case

1). 介绍

case 结构及作用,和我们在基础篇中所讲解的流程控制函数很类似。有两种语法格式:
语法 1
-- 含义: 当case_value的值为 when_value1时,执行statement_list1,当值为 when_value2时,
执行statement_list2, 否则就执行 statement_list
CASE case_value
WHEN when_value1 THEN statement_list1
[ WHEN when_value2 THEN statement_list2] ...
[ ELSE statement_list ]
END CASE;

语法2

-- 含义: 当条件search_condition1成立时,执行statement_list1,当条件search_condition2成
立时,执行statement_list2, 否则就执行 statement_list
CASE
WHEN search_condition1 THEN statement_list1
[WHEN search_condition2 THEN statement_list2] ...
[ELSE statement_list]
END CASE;

2). 案例

根据传入的月份,判定月份所属的季节(要求采用 case 结构)。
1-3 月份,为第一季度
4-6 月份,为第二季度
7-9 月份,为第三季度
10-12 月份,为第四季度
create procedure p6(in month int)
begin
declare result varchar(10);
case
when month >= 1 and month <= 3 then
set result := '第一季度';
when month >= 4 and month <= 6 then
set result := '第二季度';
when month >= 7 and month <= 9 then
set result := '第三季度'; 
when month >= 10 and month <= 12 then
set result := '第四季度';
else
set result := '非法参数';
end case ;
select concat('您输入的月份为: ',month, ', 所属的季度为: ',result);
end;
call p6(16);
如果判定条件有多个,多个条件之间,可以使用 and or 进行连接。

1.4.3while

1). 介绍

while 循环是有条件的循环控制语句。满足条件后,再执行循环体中的 SQL 语句。具体语法为:
-- 先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑
WHILE 条件 DO
SQL逻辑...
END WHILE;

2). 案例

计算从 1 累加到 n 的值, n 为传入的参数值。
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行减1 , 如果n减到0, 则退出循环
create procedure p7(in n int)
begin
declare total int default 0;
while n>0 do
set total := total + n;
set n := n - 1;
end while;
select total;
end;
call p7(100);

1.4.4repeat

1). 介绍

repeat 是有条件的循环控制语句 , 当满足 until 声明的条件的时候,则退出循环 。具体语法为:
-- 先执行一次逻辑,然后判定UNTIL条件是否满足,如果满足,则退出。如果不满足,则继续下一次循环
REPEAT
SQL逻辑...
UNTIL 条件
END REPEAT;

2). 案例

计算从 1 累加到 n 的值, n 为传入的参数值。 ( 使用 repeat 实现 )
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环
create procedure p8(in n int)
begin
declare total int default 0;
repeat
set total := total + n;
set n := n - 1;
until n <= 0
end repeat;
select total;
end;
call p8(10);
call p8(100);

1.4.5 loop

1). 介绍

LOOP 实现简单的循环,如果不在 SQL 逻辑中增加退出循环的条件,可以用其来实现简单的死循环。 OOP 可以配合一下两个语句使用: LEAVE :配合循环使用,退出循环。
ITERATE :必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环。

[begin_label:] LOOP
SQL逻辑...
END LOOP [end_label]; 
LEAVE label; -- 退出指定标记的循环体
ITERATE label; -- 直接进入下一次循环
上述语法中出现的 begin_label end_label label 指的都是我们所自定义的标记。

2). 案例一

计算从 1 累加到 n 的值, n 为传入的参数值。
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx
create procedure p9(in n int)
begin

declare total int default 0;

sum:loop

if n<=0 then
leave sum;
end if;
set total := total + n;
set n := n - 1;
end loop sum;
select total;
end;
call p9(100);

3). 案例二

计算从 1 n 之间的偶数累加的值, n 为传入的参数值。
-- A. 定义局部变量, 记录累加之后的值;
-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx
-- C. 如果当次累加的数据是奇数, 则直接进入下一次循环. --------> iterate xx
create procedure p10(in n int)
begin
declare total int default 0;
sum:loop
if n<=0 then
leave sum;
end if;
if n%2 = 1 then
set n := n - 1;
iterate sum;
end if;
set total := total + n;
set n := n - 1;
end loop sum;
select total;
end;
call p10(100);

1.4.6

1). 介绍

游标( CURSOR )是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、 OPEN FETCH CLOSE ,其语法分别如下。
x

A. 声明游标

DECLARE 游标名称 CURSOR FOR 查询语句 ;

B. 打开游标

OPEN 游标名称 ;

C. 获取游标记录

FETCH 游标名称 INTO 变量 [, 变量 ] ;

D. 关闭游标

CLOSE 游标名称 ;

2). 案例

根据传入的参数 uage ,来查询用户表 tb_user 中,所有的用户年龄小于等于 uage 的用户姓名
name )和专业( profession ),并将用户的姓名和专业插入到所创建的一张新表
(id,name,profession) 中。
-- 逻辑:
-- A. 声明游标, 存储查询结果集
-- B. 准备: 创建表结构
-- C. 开启游标
-- D. 获取游标中的记录
-- E. 插入数据到新表中
-- F. 关闭游标
create procedure p11(in uage int)
begin
declare uname varchar(100);
declare upro varchar(100);
declare u_cursor cursor for select name,profession from tb_user where age <=
uage;
drop table if exists tb_user_pro;
create table if not exists tb_user_pro(
id int primary key auto_increment,
name varchar(100),
profession varchar(100)
);
open u_cursor;
while true do
fetch u_cursor into uname,upro;
insert into tb_user_pro values (null, uname, upro);
end while;
close u_cursor;
end;
call p11(30);
上述的存储过程,最终我们在调用的过程中,会报错,之所以报错是因为上面的 while 循环中,并没有退出条件。当游标的数据集获取完毕之后,再次获取数据,就会报错,从而终止了程序的执行。

 

但是此时, tb_user_pro 表结构及其数据都已经插入成功了,我们可以直接刷新表结构,检查表结构中的数据。

 

上述的功能,虽然我们实现了,但是逻辑并不完善,而且程序执行完毕,获取不到数据,数据库还报错。 接下来,我们就需要来完成这个存储过程,并且解决这个问题。
要想解决这个问题,就需要通过 MySQL 中提供的 条件处理程序 Handler 来解决。

1.4.7条件处理程序

1). 介绍

条件处理程序( Handler )可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。具体语法为:
DECLARE handler_action HANDLER FOR condition_value [, condition_value]
... statement ;
handler_action 的取值:
CONTINUE: 继续执行当前程序
EXIT: 终止执行当前程序
condition_value 的取值:
SQLSTATE sqlstate_value: 状态码,如 02000
SQLWARNING: 所有以01开头的SQLSTATE代码的简写
NOT FOUND: 所有以02开头的SQLSTATE代码的简写
SQLEXCEPTION: 所有没有被SQLWARNING 或 NOT FOUND捕获的SQLSTATE代码的简写

2). 案例

我们继续来完成在上一小节提出的这个需求,并解决其中的问题。
根据传入的参数 uage ,来查询用户表 tb_user 中,所有的用户年龄小于等于 uage 的用户姓名
name )和专业( profession ),并将用户的姓名和专业插入到所创建的一张新表
(id,name,profession) 中。
A. 通过 SQLSTATE 指定具体的状态码
-- 逻辑:
-- A. 声明游标, 存储查询结果集
-- B. 准备: 创建表结构
-- C. 开启游标
-- D. 获取游标中的记录
-- E. 插入数据到新表中
-- F. 关闭游标
create procedure p11(in uage int)
begin
declare uname varchar(100);
declare upro varchar(100);
declare u_cursor cursor for select name,profession from tb_user where age <=
uage;
-- 声明条件处理程序 : 当SQL语句执行抛出的状态码为02000时,将关闭游标u_cursor,并退出
declare exit handler for SQLSTATE '02000' close u_cursor;
drop table if exists tb_user_pro;
create table if not exists tb_user_pro(
id int primary key auto_increment,
name varchar(100),
profession varchar(100)
);
open u_cursor;
while true do
fetch u_cursor into uname,upro;
insert into tb_user_pro values (null, uname, upro);
end while;
close u_cursor;
end;
call p11(30);
B. 通过 SQLSTATE 的代码简写方式 NOT FOUND
02 开头的状态码,代码简写为 NOT FOUND
create procedure p12(in uage int)
begin
declare uname varchar(100);
declare upro varchar(100);
declare u_cursor cursor for select name,profession from tb_user where age <=
uage;
-- 声明条件处理程序 : 当SQL语句执行抛出的状态码为02开头时,将关闭游标u_cursor,并退出
declare exit handler for not found close u_cursor;
drop table if exists tb_user_pro;
create table if not exists tb_user_pro(
id int primary key auto_increment,
name varchar(100),
profession varchar(100)
);
open u_cursor;
while true do
fetch u_cursor into uname,upro;
insert into tb_user_pro values (null, uname, upro);
end while;
close u_cursor;
end;
call p12(30);

♥️关注,就是我创作的动力

♥️点赞,就是对我最大的认可

♥️这里是小刘,励志用心做好每一篇文章,谢谢大家

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677400.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu20.4服务器搭建ftp并连接(阿里云服务器)

首先在控制台添加ftp防火墙规则&#xff1a; 然后进入服务器安装ftp&#xff08;安装vsftpd&#xff09;: sudo apt update sudo apt install vsftpd使用以下命令检查其状态&#xff1a; sudo service vsftpd status如果FTP服务器未运行&#xff0c;请使用以下命令启动它&am…

强化学习:时序差分算法 TD-learning

例子引入 首先&#xff0c;我们考虑简单的平均估计计算&#xff1a; w E [ X ] wE[X] wE[X]&#xff0c;根据 RM算法 计算过程如下&#xff1a; 接着上面的例子&#xff0c;我们现在考虑一个较为复杂的问题&#xff0c;估计函数 v ( X ) v(X) v(X) 的平均值&#xff0c;根据 …

3.数据模型

文章目录 前言1.对象&#xff08;Object&#xff09;1.1 标准对象1.2 自定义对象1.2.1 创建一个property&#xff08;房产&#xff09;自定义对象1.2.2创建一个Favorite&#xff08;收藏夹&#xff09;自定义对象1.2.3 创建对象的注意事项 1.3 字段1.3.1 为property object创建…

迅镭激光参展CESC2023中国(江苏)国际储能大会,共话储能产业发展趋势!

2023年6月14日 中国(江苏)国际储能大会 暨智慧储能技术及应用展览会 在南京国际博览中心隆重开幕 迅镭激光携多款新能源解决方案 精彩亮相A区5C21展位 聚焦新能源电池绿色智能制造 共话储能行业创新发展之路 本次展会为期三天(6月14-16日) 诚邀广大行业同仁莅临参观交流! 本届大…

全志V3S嵌入式驱动开发(spi-nor驱动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 所谓的spi nor驱动&#xff0c;其实就是让spi nor芯片&#xff0c;在linux kernel 5.2.y启动后可以被正确地识别到。前面有一篇文章&#xff0c;我…

POSIX信号量(基于生产消费模型)

目录 &#x1f34a;一、信号量 1.1之前代码的不足之处 1.2什么是信号量 &#x1f34a;二、信号量接口 &#x1f34a;三、信号量版本的生产消费模型 ①单生产单消费 ②多生产多消费 &#x1f34a;四、线程池 &#x1f34a;五、线程安全的单例模式 &#x1f34a;六、其他常…

大模型高效微调综述下: DiffPruning、BitFit、LoRa、AdaLoRA、MAM Adapters、UniPELT

文章目录 四、Selective Methods4.1 DiffPruning&#xff08;2020.10&#xff09;4.2 BitFit&#xff08;2021.6&#xff09;4.3 Freeze and Reconfigure (FAR&#xff0c;2022)4.4 FishMask&#xff08;略&#xff09; 五、Reparametrization-based methods&#xff08;重参数…

Selenium自动化工具集 - 完整指南和使用教程

文章目录 Selenium 的概述&#xff1a;Selenium 的安装与环境配置&#xff1a;Selenium WebDriver 的基本概念&#xff1a;定位元素的方法&#xff1a;常用操作方法&#xff1a;获取所有的 cookie&#xff1a;获取指定名称的 cookie&#xff1a;添加 cookie&#xff1a;删除指定…

JavaFX应用开发教程——基于JDK9与NetBeans实现

ISBN: 978-7-302-61499-9 作者&#xff1a;宋波 页数&#xff1a;257页 阅读时间&#xff1a;2023-06-18 推荐指数&#xff1a;★★★★★ 《JavaFX应用开发教程——基于JDK9与NetBeans实现》 是目前市面上讲解Java桌面开发为数不多的教材 &#xff08;JavaFX是Java语言的下一代…

Flutter系列(十二)实现购物车和提交订单页

基础工程&#xff1a; Flutter系列&#xff08;十一&#xff09;实现商城首页和商品详情页_摸金青年v的博客-CSDN博客 Flutter系列&#xff08;四&#xff09;底部导航顶部导航图文列表完整代码_摸金青年v的博客-CSDN博客 一、前言 本文用flutter实现购物车和提交订单页&#x…

【裸机开发】认识中断向量表(设置中断向量偏移的原因)

之前的LED驱动不存在中断&#xff0c;也就不包含中断的初始化。如果程序包含了中断&#xff0c;我们应还需要初始化哪些内容&#xff1f;要解决这个问题&#xff0c;我们需要先了解一个中断系统包含了哪些内容。 ① 中断向量表&#xff1a;描述中断对应的中断服务函数&#xf…

数据结构——栈的实现(动态增长版本)

堆栈&#xff08;stack&#xff09;又称为栈或堆叠&#xff0c;是计算机科学中的一种抽象资料类型&#xff0c;只允许在有序的线性资料集合的一端&#xff08;称为堆栈顶端&#xff0c;top&#xff09;进行加入数据&#xff08;push&#xff09;和移除数据&#xff08;pop&…

【软件架构】流水线设计模式

流水线模式 流水线模式是一种软件设计模式&#xff0c;它提供了构建和执行一系列操作的能力。 此模式最好与插件模式结合使用&#xff0c;以便在应用程序启动时动态构建流水线。 顺序 流水线的最基本实现是一个简单的操作序列。 public interface IOperation<T>{void …

【学习笔记】关于transformer

1.Embedding 一文读懂Embedding的概念&#xff0c;以及它和深度学习的关系 - 知乎 one-hot编码当矩阵过于稀疏时计算开销大&#xff0c;于是加上Embedding层&#xff0c;通过Embedding层&#xff08;矩阵乘法&#xff09;实现降维。 Embedding层将一个一个词&#xff08;词源…

Spring Boot 如何使用 Spring Security 进行认证和授权

Spring Boot 如何使用 Spring Security 进行认证和授权 在 Web 应用程序中&#xff0c;认证和授权是非常重要的功能。Spring Security 是一个基于 Spring 框架的强大的安全框架&#xff0c;它提供了完整的认证和授权解决方案&#xff0c;并且可以轻松地集成到 Spring Boot 应用…

gtk_table_attch与gtk_grid_attach的区别

gtk_table_attch与gtk_grid_attach的区别 button gtk_button_new_with_label (“Short fat button”); gtk_table_attach (GTK_TABLE (table), button, 0, 2, 3, 4, xoptions, yoptions, 0, 0); 0—2–3—4 左 右 上 下 /* 横线从左边的0移到右边的2&#xff0c;竖线从上边的…

3 python进阶篇

文章目录 面向对象类属性和类方法类属性类方法静态方法 单例模式__new__ 方法类实现单例模式 异常 、模块和包异常自定义异常 模块和包模块的搜索顺序包的init文件发布模块&#xff08;了解&#xff09; 文件seek文件/目录的常用管理操作eval函数 补充性知识位运算小技巧 参考我…

软考A计划-系统集成项目管理工程师-一般补充知识-中

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

【LeetCode热题100】打卡第27天:二叉树的前序、中序、后序遍历

文章目录 【LeetCode热题100】打卡第27天&#xff1a;二叉树的前序、中序、后序遍历⛅前言&#x1f4d5;二叉树的前序遍历&#x1f512;题目&#x1f511;题解 &#x1f4d5;二叉树的中序遍历&#x1f512;题目&#x1f511;题解 &#x1f4d5;二叉树的后序遍历&#x1f512;题…

(万字长文)React 18 源码与原理解读 —— 看这一篇就够了

写在专栏开头&#xff08;叠甲&#xff09; 作者并不是前端技术专家&#xff0c;也只是一名喜欢学习新东西的前端技术小白&#xff0c;想要学习源码只是为了应付急转直下的前端行情和找工作的需要&#xff0c;这篇专栏是作者学习的过程中自己的思考和体会&#xff0c;也有很多参…