MySQL存储过程及语法详解


Posted in MySQL onAugust 05, 2022

1. 存储过程基本用法

1.1 概念

  • 存储过程,也叫做存储程序,是一条或者多条SQL语句的集合,可以视为批量处理,但是其作用不仅仅局限于批量处理。
  • 其中针对存储过程也有多种操作:如何创建存储过程,以及如何调用、查看、修改、删除存储过程。存储过程也可以调用其他存储过程。(类似于Java函数之间的相互调用)
  • 存储过程和函数是:事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据库和应用之间的传输,对于提高数据处理的效率是非常有好处的。

函数:是一个有返回值的过程;过程:是一个没有返回值的函数

存储过程和自定义函数的区别:

  • 存储过程实现的功能要复杂一些;而函数的针对性更强。
  • 存储过程可以返回多个值;函数只能有一个返回值。
  • 存储过程一般独立的来执行;而函数可以作为其他SQL语句的组成部分实现出来。

1.2 创建存储过程

1.2.1 语法格式

# 这个地方其实是用来声明SQL语句的结束符号的
delimiter //
​
# 这个地方此时真正的用来创建一个存储过程的
create procedure 存储过程名称(参数列表)
begin
    -- sql语句
end// 
​
# 当创建完一个存储过程之后再将分隔符替换为分号,为了不影响其他的操作
delimiter ;

2.2.2 语法介绍

  • delimiter : 用于设置sql语句分割符,默认为分号。因为在MySQL中每一条SQL语句都必须以 ;进行结束,当我们换行的时候就会执行这条SQL语句,但是我们此时的存储过程并没有结束,就会造成直接执行没有写完的存储过程造成报错,所以此时需要声明其他的结束符,不让其使用默认的分隔符结束SQL语句。
  • sql语句 :在这个部分编写sql语句,编写的语句需要以分号结尾,此时回车会直接执行,所以要创建存储过程前需要指定其他符号作为分割符,此时使用 // , 也可以使用其它字符。
  • // : 声明结束符号,这个符号可以是任意的,是自定义的。相当于就是把 分号替换为 //

创建存储过程查询学生信息

# 将SQL语句的结束符号分隔符替换为//
delimiter //
​
create procedure proc_stu()
begin
select * from students; # 此时这个分号并不会结束这个语句,存储过程中的SQL语句还是用分隔符进行分隔
end // # 这里使用这个结束符号代表这个存储过程创建完成
​
delimiter; # 创建完一个存储过程之后将结束符号替换为分号,防止进行其他操作的时候有问题

1.3 调用存储过程

语法格式:

call proc_stu(); # 调用的时候需要加上括号,因为可能存在参数

1.4 查看存储过程

语法格式:

# 查询 studnet 数据库中的所有的存储过程
select name from mysql.proc where db='studnet';
​
# 查询存储过程的状态信息
show procedure status;

1.5 删除存储过程

语法格式:

drop procedure proc_stu; # 删除的时候不要加小括号,直接给定存储过程的名字即可。
drop procedure if exists proc_stu; # 如果存储删除,不存在不删除并且不会报错

2. 存储过程中的语法结构

  • 存储过程是可以编程的,意味着可以使用变量、表达式、控制语句来完成比较复杂的功能。

2.1 变量的声明以及赋值

2.1.1 DECLARE 声明变量

DECLARE : 通过 DECLARE 关键字可以定义一个局部变量,该变量的作用范围只能在 BEGIN..,END 块中。

语法格式:

DECLARE 变量名[,...] type [DEFAULT value]

注意:声明变量的时候可以一次性声明多个,使用逗号隔开。

示例:

delimiter $
create procedure proc_stu()
begin
    declare num int default 5;
    select num + 10; # 输出结果为15
end $
delimiter ;

2.1.2 SET 变量赋值

SET : 直接赋值使用SET关键字,可以赋常量或者是表达式,具体语法如下:

SET 变量名 = 变量值 [,变量名 = 变量值] ...

注意:一次可以给多个变量赋值,中间使用逗号隔开。

delimiter $​
create procedure proc_stu()
begin
    declare name varchar(20);  # 可以指定变量类型以及变量的范围
    set name = 'MySQL';  # 给变量直接赋值
    select name; # 输出结果为:MySQL
end $
​
delimiter ;

2.1.3 select...into 赋值

delimiter $​
create procedure proc_student()
begin
    declare count_num int(10);
    select count(*) into count_num from student;
    select count_num;
end $
​
delimiter ;

2.2 条件判断

2.2.1 if条件判断

语法结构:

# 只有满足差选条件才会执行 then 后面的SQL语句
if search_condition(查询条件) then statement_list(SQL语句)
    [else if search_condition(查询条件) then statement_list(SQL语句)]...
    [else statement_list(SQL语句)]
end if;

需求:

根据身高,判断当前身高所属的身材类型
    180及以上 --------> 身材高挑
    170 - 180 --------> 标准身材
    170以下 ----------> 一般身材

实现这个简单的逻辑:

delimiter $
​create procedure pro_figure()
begin 
    # 定义一个身高的变量
    declare height int(11) default 175;
    # 定义一个存储身高类型的变量
    declare figure varchar(50) default '';
    # 使用 if 语句判断身材类型
    if height >= 180 then 
        set figure = '身材高挑';
    else if height < 180 and height >= 170 then
        set figure = '标准身材';
    else set figure = '一般身材';
    end if;
    # 输出结果
    select concat(height + '身高的身材为:' + figure);
end $
​
delimiter ;

2.3 传递参数

语法格式:

delimiter $
​
# 我们可以不指定 [in/out/inout] , 默认为 in,输入参数  
create procedure pro_name([in/out/inout]参数名 参数类型)
begin 
    -- sql语句
end $
delimiter ;

# in : 该参数可以作为输入,调用该存储过程需要传入的值,默认
# out : 该参数作为输出,调用该存储过程之后返回的值。
# inout : 既可以作为输入参数也可以作为输出参数。

2.3.1 IN - 输入参数

需求:根据输入的身高变量的值,判断当前身高对应的身材类型

实现:

delimiter $
# 此时调用者在调用这个存储过程的时候必须传递身高的变量值
create procedure pro_name(in height int(11))
begin 
    # 定义一个存储身高类型的变量
    declare figure varchar(50) default '';
    # 使用 if 语句判断身材类型
    if height >= 180 then 
        set figure = '身材高挑';
    else if height < 180 and height >= 170 then
        set figure = '标准身材';
    else set figure = '一般身材';
    end if;
    # 输出结果
    select concat(height + '身高的身材为:' + figure);
end $
​
delimiter ;

调用:

# 调用该存储过程。需要传递其中的身高值
call pro_name(175);  # 输出结果为:

2.3.2 out - 输出参数

需求:根据输入的身高,返回当前身高所处的身材类型

实现:

delimiter $​
create procedure pro_output(in height int(11) , out figure varchar(100))
begin 
    # 使用 if 语句判断身材类型
    if height >= 180 then 
        set figure = '身材高挑';
    else if height < 180 and height >= 170 then
        set figure = '标准身材';
    else set figure = '一般身材';
    end if;
end $
delimiter ;

调用:

# @标识符:在MySQL中代表的就是用户定义的一个变量,这里我们使用这个变量来接收这个存储过程的返回值
call pro_output(175 , @figure);
​
# 查看存储过程返回的结果
select @figure;

@标识符的作用

  • @figure :这种在变量名前面加上”@“符号,叫做用户会话变量,代表整个会话过程他都是有作用的,这个类似于全局变量一样。当前会话就是代表的,比如我们在命令提示窗口中给好多带有 @ 符号变量进行赋值,此时这些变量的值只作用于当前的会话,当我们把这个窗口关闭的时候,此时这些变量的值就会释放掉。
  • @@global : 这种在变量名前加上 "@@" 符号,叫做系统变量。

2.4 case 结构

语法格式:

# 方式一
case case_value(判断的值)
    when when_value(比较的值) then statement_list(SQL语句)
    [when when_value(比较的值) then statement_list(SQL语句)]...
    [else statement_list(SQL语句)]
end case;
​
# 方式二
case 
    when search_condition(查询条件) then statement_list(SQL语句)
    [when search_condition(查询条件) then statement_list(SQL语句)]...
    [else statement_list(SQL语句)]
end case;

需求:给定一个月份,判断该月份所属的季度

实现:

delimiter $​
create procedure pro_quarter(in mon int(11))
begin 
    # 定义存储季度的变量
    declare result varchar(10);
    case 
        when mon >= 1 and mon <= 3 then
            set result = '第一季度';
        when mon >= 4 and mon <= 6 then
            set result = '第一季度';
        when mon >= 7 and mon <= 9 then
            set result = '第一季度';
        else
            set result = '第四季度';
        end case;
    # 输出结果
    select result;  
end $
​
delimiter ;

2.5 while循环

有条件的循环控制语句,当满足条件的时候进入循环,不满足条件的时候退出循环。

语法结构:

# 只要查询条件一直成立就会一直指定do后面的SQL语句,当查询条件不成立的时候直接跳出while循环
while search_condition(查询条件) do
    statement_list(SQL语句)
end while;

需求:计算从1加到n的值

实现:

delimiter $​
create procedure pro_sum(in num int(11))
begin 
    # 定义存储总数的变量
    declare total int(255) default 0;
    # 定义存储循环次数的数量
    declare number int(255) default 1;
    while number <= num do
        set total = total + number;
        set number = number + 1;
    end while;
    select total;
end $
​
delimiter ;

2.6 repeat循环

有条件的循环控制语句,当不满足条件的时候进入循环,满足条件的时候跳出循环。他和while循环是反着的

语法结构:

repeat 
    statement_list(SQL语句)
    until search_condition(查询添加)
end repeat;

需求:计算从1加到n的值

实现:

delimiter $​
create procedure pro_sum(in num int(11))
begin 
    # 定义存储总数的变量
    declare total int(255) default 0;
    repeat 
        set total = total + number;
        set num = num - 1;
        # 注意:这个 unti 后的查询条件不要加分号,加分号会报错。
        until num = 0
    end repeat;
    select total;
end $
​
delimiter ;

2.7 loop循环

loop实现简单的循环,退出循环的条件需要使用其他的语句定义,通常可以使用leave语句实现,具体语法如下:

语法格式:

[begin_label:] loop
    statement_list
end loop [end_label]

如果不在statement_list中增加退出循环的语句,那么loop语句可以永安里实现简单的死循环。

2.8 leave语句

用来从标注的流程构造中退出,通常和 begin...end 或循环一起使用。下面是一个使用loop和leave的简单例子,退出循环:

需求:计算从1加到n的值 ---> 使用loop...leave的形式进行退出循环

实现:

delimiter $
create procedure pro_sum(in num int(11))
begin 
    # 定义存储总数的变量
    declare total int(255) default 0;
    
    c(该循环的别名):loop
        set total = total + num;
        set num = num - 1;
        # 借助leave组织退出条件
        if num <= 0 then
            leave c;
        end if; 
    end loop c;
    select total;
end $
delimiter ;

到此这篇关于MySQL存储过程及语法详解的文章就介绍到这了,更多相关MySQL存储语法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL之高可用集群部署及故障切换实现
Apr 22 MySQL
MySQL 覆盖索引的优点
May 19 MySQL
分析mysql中一条SQL查询语句是如何执行的
Jun 21 MySQL
通过shell脚本对mysql的增删改查及my.cnf的配置
Jul 07 MySQL
浅谈MySQL之select优化方案
Aug 07 MySQL
MySQL去除重叠时间求时间差和的实现
Aug 23 MySQL
MySQL定时备份数据库(全库备份)的实现
Sep 25 MySQL
MySQL 数据类型详情
Nov 11 MySQL
mysql中数据库覆盖导入的几种方式总结
Mar 25 MySQL
MySQL Server 层四个日志
Mar 31 MySQL
MySQL提取JSON字段数据实现查询
Apr 22 MySQL
解决Mysql报错 Table 'mysql.user' doesn't exist
May 06 MySQL
MySQL自定义函数及触发器
Aug 05 #MySQL
MySQL性能指标TPS+QPS+IOPS压测
Aug 05 #MySQL
Mysql中mvcc各场景理解应用
Aug 05 #MySQL
数据设计之权限的实现
一文解答什么是MySQL的回表
Aug 05 #MySQL
MySQL一劳永逸永久支持输入中文的方法实例
Aug 05 #MySQL
SQLServer常见数学函数梳理总结
Aug 05 #MySQL
You might like
业余方法DIY电子管FM收音机
2021/03/02 无线电
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
PHP registerXPathNamespace()函数讲解
2019/02/03 PHP
js实现的网页颜色代码表全集
2007/07/17 Javascript
javascript打开新窗口同时关闭旧窗口
2009/01/16 Javascript
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
javascript jscroll模拟html元素滚动条
2012/12/18 Javascript
js 利用image对象实现图片的预加载提高访问速度
2013/03/29 Javascript
javascript打印输出json实例
2013/11/11 Javascript
Javascript 计算字符串在localStorage中所占字节数
2015/10/21 Javascript
深入理解JQuery中的事件与动画
2016/05/18 Javascript
老生常谈javascript的面向对象思想
2017/08/22 Javascript
详解Nodejs 通过 fs.createWriteStream 保存文件
2017/10/10 NodeJs
Vue三种常用传值示例(父传子、子传父、非父子)
2018/07/24 Javascript
vue使用ajax获取后台数据进行显示的示例
2018/08/09 Javascript
使用FormData实现上传多个文件
2018/12/04 Javascript
vue项目中使用bpmn为节点添加颜色的方法
2020/04/30 Javascript
[43:41]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
Python实现爬虫抓取与读写、追加到excel文件操作示例
2018/06/27 Python
python 运用Django 开发后台接口的实例
2018/12/11 Python
Python 转换文本编码实现解析
2019/08/27 Python
python实现梯度下降法
2020/03/24 Python
Python生成随机验证码代码实例解析
2020/06/09 Python
Python实现快速大文件比较代码解析
2020/09/04 Python
日本面向世界,国际级的免税在线购物商城:DOKODEMO
2017/02/01 全球购物
explicit和implicit的含义
2012/11/15 面试题
给领导的致歉信范文
2014/01/13 职场文书
大型车展策划方案
2014/02/01 职场文书
运动会口号8字
2014/06/07 职场文书
乡镇个人对照检查材料
2014/08/22 职场文书
2014年高一班主任工作总结
2014/12/05 职场文书
教师个人成长总结
2015/02/11 职场文书
2015年试用期自我评价范文
2015/03/10 职场文书
售后服务质量承诺书
2015/04/29 职场文书
小学运动会加油稿
2015/07/22 职场文书
2019班干部竞选演讲稿范本!
2019/07/08 职场文书