数据库之九 流程控制、存储过程和函数

【零】数据准备

【1】创建用户信息表

(1)创建表
  • id:编号
  • name:用户名
  • sex:性别,默认男
  • balance:余额
  • register_time:注册时间
drop table if exists user;
create table user(
id int auto_increment primary key,
name varchar(20),
sex enum('female', 'male') default 'male',
balance float(8, 2),
register_time datetime);
(2)插入数据
truncate user;
insert user(name, sex, balance, register_time)
values('bruce', 'male', 1642.79, '2022-07-01 10:21:31'),
('alice', 'female', 2546.55, '2022-07-02 12:45:20'),
('john', 'male', 125.74, '2022-08-03 08:15:47'),
('emma', 'female', 2651.23, '2022-08-04 16:30:12'),
('mike', 'male', 852.90, '2022-09-05 09:54:38');

【一】流程控制

  • 需要在存储过程或函数中使用

【1】什么是流程控制

(1)说明
  • 流程控制是编程中一种用于控制程序执行流程的机制,通常涉及条件判断、循环和分支等结构。

  • 在数据库中的存储过程、触发器、以及一些脚本语言中,流程控制结构用于根据不同条件执行不同的代码块,从而实现更为复杂和灵活的逻辑。

  • 在数据库中,流程控制结构的主要目的是在 SQL 语句的基础上提供更强大的编程能力,使得可以实现更复杂的业务逻辑。

【2】变量

  • 在 MySQL 中,有多种类型的变量,包括系统变量、用户定义变量和存储过程中的局部变量。
(1)系统变量
  • 系统变量是 MySQL 服务器上的全局配置参数,它们影响着 MySQL 的整体行为。

  • 可以使用 SHOW VARIABLES; 查询当前服务器上的所有系统变量。

  • 例如:

    • max_connections:这是系统允许的最大连接数量
show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 200   |
+-----------------+-------+
(2)自定义变量
  • 用户定义变量是在会话中由用户创建和使用的变量。
  • 这些变量的名字以 @ 符号为前缀。
  • 用户定义变量的值在连接会话期间保持有效,连接结束后失效。
  • 例如:
    • 定义并查看变量name
set @name = 'bruce';
select @name;
(3)局部变量
  • 在存储过程中,可以声明局部变量,这些变量仅在存储过程的执行期间存在,超出存储过程的范围后被销毁。

  • 语法:

declare 变量名 类型

【3】条件判断

(1)if else
  • 根据条件判断是否执行某个操作。
if 条件 then-- 执行内容
elseif 条件 then-- 执行内容
else-- 执行内容
end if;	

【4】多分支体条件判断

  • 在满足条件的情况下反复执行一组语句
(1)case
casewhen 条件1 then -- 执行内容when 条件2 then -- 执行内容......else-- 执行内容
end case;	

【5】循环结构

  • 在满足条件的情况下反复执行一组语句
(1)while
while 条件 do-- 执行内容
end while;	
(2)repeat until
repeat-- 执行内容
until 条件;	
(3)loop
loop-- 执行内容
end loop;	
(4)for
for 变量 in 多内容 do-- 执行内容
end for;	

【5】退出循环结构

  • 循环中满足某个条件退出
(1)leave
while 条件 do-- 执行内容if 条件 thenleave;end if;	
end while;	

【二】存储过程

【1】说明

(1)什么是存储过程
  • 存储过程是在数据库中预先定义的一组SQL语句,可以接收参数并返回结果。
  • 它们在数据库服务器中保存,可以通过应用程序调用,执行特定的数据库操作。
  • 存储过程的使用有助于提高数据库的可维护性、安全性,并可以提高性能,因为它们可以在数据库服务器上直接执行,减少了与应用程序之间的通信开销。
  • 理解为自定义函数
(2)特点
  • 预编译: 存储过程在创建时进行编译和优化,执行时无需重复编译,提高数据库执行效率。
  • 数据库端执行: 存储过程在数据库服务器端执行,减少了与应用程序之间的网络传输开销,提高了数据访问性能。
  • 代码重用: 存储过程可被多个应用程序共享和重用,避免了重复编写相同的SQL语句,提高了开发效率。
  • 安全性: 通过存储过程,可以限制对数据库的访问权限,提高数据的安全性。
  • 事务支持: 存储过程可以包含事务处理逻辑,确保数据库操作的一致性和完整性。
  • 简化复杂操作: 存储过程能执行复杂的数据操作和计算,简化了应用程序的开发和维护过程。

【2】存储过程的开发模式

  • 命令式开发模式(Imperative Development Model)

    • 存储过程以类似编程语言的方式编写,包括条件语句、循环结构和异常处理等。

    • 逻辑较为灵活,但容易导致存储过程复杂难懂,维护困难。

  • 声明式开发模式(Declarative Development Model)

    • 存储过程的逻辑更关注数据操作语句,如查询、插入、更新和删除等。

    • 通过声明数据操作的目标和条件来实现,逻辑简洁明了,更易于理解和维护。

  • 触发器开发模式(Trigger Development Model)

    • 触发器是一种特殊的存储过程,与数据库表相关联,在预定义的事件发生时自动触发执行。

    • 用于实现数据一致性、数据验证、日志记录等功能。

    • 开发模式与其他存储过程略有不同,执行时机和上下文由数据库事件触发,而不是外部调用。

【3】使用

(1)创建存储过程
  • 创建存储过程模板
    • in是传入参数
    • out是返回参数
delimiter $$
create procedure 存储器名(in 形参 类型, in 形参 类型, out 形参 类型)
begin--执行语句
end $$
delimiter ;
  • 创建一个存储过程
    • 通过输入用户的名字和金额
    • 对用户进行充值
delimiter $$
create procedure my_func_recharge(in n varchar(20), in m float(8, 2), out res varchar(20))
begindeclare name_exists int;select count(*) into name_existsfrom user where name = n;if name_exists > 0 thenupdate userset balance = balance + mwhere name = n;set res = '充值成功';elseset res = '充值失败,名字不存在';end if;
end $$
delimiter ;
(2)查看存储过程创建信息
  • 语法
show create procedure 存储过程名字 \G;
show create procedure my_func_recharge \G;
mysql> show create procedure my_func_recharge \G;
*************************** 1. row ***************************Procedure: my_func_rechargesql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTHCreate Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `my_func_recharge`(in n varchar(20), in m float(8, 2), out res varchar(20))
begindeclare name_exists int;select count(*) into name_existsfrom user where name = n;if name_exists > 0 thenupdate userset balance = balance + mwhere name = n;set res = '充值成功';elseset res = '充值失败,名字不存在';end if;
end
character_set_client: utf8mb4
collation_connection: utf8mb4_general_ciDatabase Collation: utf8mb4_general_ci
1 row in set (0.00 sec)ERROR:
No query specified
(3)查看所有存储过程(过多)
  • 语法
show procedure status;
(4)调用存储过程
  • 语法
call 存储过程名字(参数);
  • 测试
    • 成功
# 查看原来的金额
select balance from user where name = 'bruce';
+---------+
| balance |
+---------+
| 1642.79 |
+---------+
# 充值测试
set @res = ''
call my_func_recharge('bruce', 100.5, @res);
# 查看标志位
select @res;
+--------------+
| @res         |
+--------------+
| 充值成功     |
+--------------+
# 查看金额
+---------+
| balance |
+---------+
| 1743.29 |
+---------+
# 名字错误测试
call my_func_recharge('bbruce', 100.5, @res);
select @res;
+--------------------------------+
| @res                           |
+--------------------------------+
| 充值失败,名字不存在           |
+--------------------------------+
(5)删除存储过程
  • 语法
drop procedure if exists 存储过程名称;
drop procedure if exists my_func_recharge;

【三】函数

  • 前面的存储过程就相当于自定义函数
  • 这里的函数就相当于内置函数

【1】字符串函数

(1)concat
  • CONCAT: 将多个字符串拼接在一起。
select concat(id, "-", name) as id_name
from user limit 2;
+---------+
| id_name |
+---------+
| 1-bruce |
| 2-alice |
+---------+
(2)substring
  • SUBSTRING: 截取字符串的子串。
select substring('python', 3, 2) as res;
+------+
| res  |
+------+
| th   |
+------+
(3)char_length
  • CHAR_LENGTH: 返回字符串的字符数。
select name, char_length(name) as name_length
from user limit 3;
+-------+-------------+
| name  | name_length |
+-------+-------------+
| bruce |           5 |
| alice |           5 |
| john  |           4 |
+-------+-------------+
(4)upper/lower
  • lower():全小写
  • upper():全大写
select upper(name) as name
from user limit 3;
+-------+
| name  |
+-------+
| BRUCE |
| ALICE |
| JOHN  |
+-------+

【2】数值函数

(1)round
  • ROUND(num, decimals): 对数值进行四舍五入。
select balance as old, round(balance) as new
from user limit 3;
+---------+------+
| old     | new  |
+---------+------+
| 1743.29 | 1743 |
| 2546.55 | 2547 |
|  125.74 |  126 |
+---------+------+
(2)floor
  • FLOOR(num): 返回不大于给定数值的最大整数。
select balance as old, floor(balance) as new
from user limit 3;
+---------+------+
| old     | new  |
+---------+------+
| 1743.29 | 1743 |
| 2546.55 | 2546 |
|  125.74 |  125 |
+---------+------+
(3)ceiling
  • CEILING(num): 返回不小于给定数值的最小整数。
select balance as old, ceiling(balance) as new
from user limit 3;
+---------+------+
| old     | new  |
+---------+------+
| 1743.29 | 1744 |
| 2546.55 | 2547 |
|  125.74 |  126 |
+---------+------+
(4)abs
  • ABS(num): 返回给定数值的绝对值。

【3】日期和时间函数

(1)now
  • NOW(): 返回当前日期和时间。
select now() as time;
+---------------------+
| time                |
+---------------------+
| 2024-01-30 21:07:15 |
+---------------------+
(2)curdate
  • CURDATE(): 返回当前日期。
select curdate() as today;
+------------+
| today      |
+------------+
| 2024-01-30 |
+------------+
(3)curtime
  • CURTIME(): 返回当前时间。
select curtime() as time;
+----------+
| time     |
+----------+
| 21:09:56 |
+----------+
(4)date_formate
  • DATE_FORMAT(date, format): 格式化日期。
select date_format(register_time, '%Y-%m') as date, count(*)
from user
group by date_format(register_time, '%Y-%m');
+---------+----------+
| date    | count(*) |
+---------+----------+
| 2022-07 |        2 |
| 2022-08 |        2 |
| 2022-09 |        1 |
+---------+----------+
select * from user where date(register_time) = '2022-08-03';
+----+------+------+---------+---------------------+
| id | name | sex  | balance | register_time       |
+----+------+------+---------+---------------------+
|  3 | john | male |  125.74 | 2022-08-03 08:15:47 |
+----+------+------+---------+---------------------+
select * from user year
where month(register_time) = '07';
+----+-------+--------+---------+---------------------+
| id | name  | sex    | balance | register_time       |
+----+-------+--------+---------+---------------------+
|  1 | bruce | male   | 1642.79 | 2022-07-01 10:21:31 |
|  2 | alice | female | 2546.55 | 2022-07-02 12:45:20 |
+----+-------+--------+---------+---------------------+

【4】聚合函数

  • 详细信息查看筛选条件的group by

    • 数据库之五 筛选条件-CSDN博客
  • COUNT(column): 计算符合条件的行数。

  • SUM(column): 对指定列的值求和。

  • AVG(column): 计算指定列的平均值。

  • MIN(column): 找到指定列的最小值。

  • MAX(column): 找到指定列的最大值。

  • GROUP_CONCAT :拼接字段值或字符串。

【5】条件函数

(1)if
  • 语法
IF(condition, value_if_true, value_if_false): 如果条件成立,则返回value_if_true,否则返回value_if_false。
  • 示例
select name, if(balance > 2000, "rich", "poor") as money_con
from user;
+-------+-----------+
| name  | money_con |
+-------+-----------+
| bruce | poor      |
| alice | rich      |
| john  | poor      |
| emma  | rich      |
| mike  | poor      |
+-------+-----------+
(2)case
  • 语法
CASE WHEN condition THEN value END: 根据满足的条件返回相应的值。
  • 示例
select name,case when balance > 2500 then 'very rich'when balance > 2000 then 'rich'else'poor'end as money_con
from user;		
+-------+-----------+
| name  | money_con |
+-------+-----------+
| bruce | poor      |
| alice | very rich |
| john  | poor      |
| emma  | very rich |
| mike  | poor      |
+-------+-----------+

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

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

相关文章

KEIL指定文件夹生成:程序名字+版本号+时间的脚本

为了免去每次更新版本还需要手动更改可执行程序的名字繁琐步骤。特此参考网上一个开源脚本编写了一个脚本文件。直接上图: 1.在指定的文件中填写:#define SOFTWARE_VERSION "1.0.2" 2.将脚本添加到如下图所示位置 3.点击编译,得到…

vxe-table3.0的表格树如何做深层查找,返回搜索关键字的树形结构

vxe-table2.0版本是提供深层查找功能的,因为他的数据源本身就是树形结构,所以深层查找查询出来也是树形结构。 但是vxe-table3.0版本为了做虚拟树功能,将整个数据源由树形垂直结构变成了扁平结构,便不提供深层查询功能&#xff0c…

【PWN · ret2syscall】[CISCN 2023 初赛]烧烤摊儿

好久未做ret2syscall 一、题目分析 漏洞点,栈溢出: 然而到该漏洞点,需要“花钱”买下店铺。个人所有的零钱不够。 利用整数溢出(emmmm这里应该不算溢出漏洞,而是代码逻辑不规范,商品个数不能为负数&#x…

华为数通方向HCIP-DataCom H12-831题库(简答题01-27)

第01题 第02题 第03题 第04题 第05题 IS-IS是链路状态路由协议,使用SPF算法进行路由计算。某园区同时部署了IPV4和IPv6并运行IS-IS实现网络的互联与通。如图所示,该网络IPV4和IPV6开销相同,R1和R4只支持IPV4缺省情况下,计算形成的IPV6最短路径树中,R2访问R6的下一跳设备是…

uniapp H5 实现上拉刷新 以及 下拉加载

uniapp H5 实现上拉刷新 以及 下拉加载 1. 先上图 下拉加载 2. 上代码 <script>import DragableList from "/components/dragable-list/dragable-list.vue";import {FridApi} from /api/warn.jsexport default {data() {return {tableList: [],loadingHi…

为什么MySQL推荐使用自增主键?

为什么MySQL推荐使用自增主键&#xff1f; 主键数据记录本身被存于主索引&#xff08;一棵BTree&#xff09;的叶子节点上&#xff0c;这就要求同一个叶子节点内&#xff08;大小为一个内存页或磁盘页&#xff09;的各条数据记录按主键顺序存放&#xff0c;因此每当有一条新的记…

【JAVA】Semaphore 有什么作用

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 1. 二进制信号量&#xff1a; 2. 计数信号量&#xff1a; 结语 我的其他博客 前言 Semaphore&#xff08;信号量&#xff09;作为…

uniapp微信小程序-分包

一、为什么要分包 微信小程序每个分包的大小是2M&#xff0c;总体积一共不能超过20M,当然你也可以提升启动速度&#xff0c;降低首次加载时间&#xff0c;模块化开发&#xff0c;按需加载&#xff0c;提高性能。 二、分包步骤 1.首先在 mainfest.json mp-weixin添加以下代码&a…

ORA-01031: insufficient privileges

数据库密码过期了&#xff0c;通过如下命令&#xff1a; sqlplus / as sysdba 还是会报ORA-01031: insufficient privileges错误。 有人说是登录用户名不属于dba组造成的&#xff0c;后来 查看了用户组和用户都隶属于dba组&#xff0c;但是还是提示这个错误。 提示ORA-01…

idea创建golang项目

目录 1、设置环境 2、创建项目 3、设置项目配置 4、初始化项目 5、安装本项目的外部依赖包 6、运行项目 7、访问页面查看结果 1、设置环境 1 启用 Go Modules 功能go env -w GO111MODULEon 2. 阿里云go env -w GOPROXYhttps://mirrors.aliyun.com/goproxy/,direct上述命…

字符串:getline、删除子串.erase()函数、插入子串.insert()函数

getline具体用法&#xff1a; 1、函数形式 getline ( cin,字符串类型&#xff1a;变量名);//默认以换行符结束 getline (cin, 字符串类型&#xff1a;变量名, ‘指定的结束符’); //指定换行结束符 2注意事项&#xff1a; 1&#xff09;如果在使用getline()之前有使用scanf(…

大数据分析案例-基于随机森林算法构建电影票房预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Coppeliasim同步模式介绍

同步模式 在倒立摆demo中&#xff0c;打开 synchronous_enable True 后&#xff0c;会发现仿真变慢了&#xff0c;接下来将对同步模式进行介绍。 # simxSynchronous()函数的第一个参数是连接的ID&#xff0c;第二个参数是是否开启同步模式 vrep_sim.simxSynchronous(clien…

怎 么 优 化 H5 让 它 可 以 在 300ms 之 内

减少HTTP请求数量&#xff1a;将多个小的CSS和JavaScript文件合并为一个文件&#xff0c;减少HTTP请求的数量。可以使用工具如Webpack、Parcel等打包工具对代码进行打包合并。 使用缓存&#xff1a;通过设置适当的缓存策略&#xff0c;让浏览器缓存静态资源&#xff08;如CSS、…

Java设计模式【工厂模式】

Java设计模式【工厂模式】 前言 三种工厂模式&#xff1a;简单工厂模式、工厂方法模式、抽象工厂模式&#xff1b; 创建型设计模式封装对象的创建过程&#xff0c;将对象的创建和使用分离开&#xff0c;从而提高代码的可维护性和可扩展性 简单工厂模式 概述&#xff1a;将…

机房建设的陷阱与规范

在数字化时代&#xff0c;数据中心的建设变得愈发重要&#xff0c;然而&#xff0c;许多集成商在机房建设中存在一些常见的误区。他们往往将机房建设仅仅定义为能源设备的安装和装修&#xff0c;而忽略了甲方的网络应用、服务器应用以及网络与服务器之间的连接应用。这导致了一…

前端-Vue項目初始化

大家好我是苏麟 , 今天聊聊前端依赖 Ant Design Vue 快速初始化项目 . Ant Design Vue官网 : 快速上手 - Ant Design Vue (antdv.com) 初始化项目 1.找到文档->快速上手 脚手架命令 : npm install -g vue/cli 2.找到一个文件夹(不要在中文路径) 下打开cmd窗口输入脚手架…

设计一个本地缓存

注意点 数据结构&#xff1a; 设计用什么数据结构存储。最简单的就直接用Map来存储数据&#xff0c;或者复杂想redis一样提供了多种数据类型哈希&#xff0c;列表&#xff0c;集合&#xff0c;有序集合等&#xff0c;底层使用了双端链表&#xff0c;压缩列表&#xff0c;集合&…

威联通docker安装青龙面板

威联通容器界面改版很多&#xff0c;没直接找到新版设置方法&#xff0c;自己摸索了一下做个记录。 一、配置docker镜像源 威联通默认的库地址国内无法直接方法&#xff0c;需要先配置国内镜像源。 在容器工作者中选择“存储库”&#xff0c;点击添加 第一个“提供商”里选…

FPS游戏框架漫谈第五天

今天想了想整理下AnimatorManager 他的职责是负责动画的播放&#xff0c;那么在介绍该对象具备的对外接口&#xff0c;必须先介绍下拥有动画的对象他是怎么管理动画数据的&#xff0c;打个比方如果我们一个把武器需要播放开火动画&#xff0c;那么我们基于unity引擎可视化动画编…