【Mysql专题】存储过程介绍及其基本操作

目录

  • 一、存储过程的介绍
  • 二、存储过程的操作
    • 2.1 创建存储过程
    • 2.2 调用存储过程
    • 2.3 查看存储过程
    • 2.4 删除存储过程
  • 三、存储过程中的语法构造
    • 3.1 变量的声明以及赋值
    • 3.2 条件判断
    • 3.3 传递参数
    • 3.4 case结构
    • 3.5 while循环
    • 3.6 repeat循环
    • 3.7 loop循环与leave语句
  • 感谢

一、存储过程的介绍

基本定义
存储过程是一组为了完成特定功能的 SQL 语句集合。使用存储过程的目的是将常用或复杂的工作预先用 SQL 语句写好并用一个指定名称存储起来,这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。当以后需要数据库提供与已定义好的存储过程的功能相同的服务时,只需调用“CALL存储过程名字”即可自动完成。(对应的就是Java里面的函数)

我们通常使用的SQL 语句都是针对一个表或几个表的单条 SQL 语句,但是在数据库的实际操作中,并非所有操作都那么简单,有时候一个完整的操作需要多条 SQL 语句处理多个表才能完成。例如:为了确认学生能否毕业,需要同时查询学生档案表、成绩表和综合表。此时就需要使用多条 SQL 语句来针对几个数据表完成这个处理要求。存储过程可以有效地完成这个数据库操作。

常用操作数据库的 SQL 语句在执行的时候需要先编译,然后执行。存储过程则采用另一种方式来执行 SQL 语句。一个存储过程是一个可编程的函数,它在数据库中创建并保存,一般由 SQL 语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的特定功能时,存储过程尤为合适。
存储过程通常有如下优点:

  1. 封装性。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的 SQL 语句,并且数据库专业人员可以随时对存储过程进行修改,而不会影响到调用它的应用程序源代码
  2. 可增强 SQL 语句的功能和灵活性。存储过程可以用流程控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算
  3. 可减少网络流量。这个不难理解,以往我们使用单条sql,每次调用都需要发起一次IO请求将完整的IO请求发送过去,但是现在只需要【CALL 存储过程】就可以了。确切的说:由于存储过程是在服务器端运行的,且执行速度快,因此当客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载
  4. 高性能。存储过程执行一次后,产生的二进制代码就驻留在缓冲区,在以后的调用中,只需要从缓冲区中执行二进制代码即可,从而提高了系统的效率和性能
  5. 提高数据库的安全性和数据的完整性。使用存储过程可以完成所有数据库操作,并且可以通过编程的方式控制数据库信息访问的权限

特别声明
存储过程跟自定义函数很像。它们的区别是:

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

二、存储过程的操作

2.1 创建存储过程

语法格式如下:

CREATE PROCEDURE <过程名>(参数列表 参数类型)
BEGIN
<过程体 sql语句>
END

语法说明如下:
1)上面的CREATE PROCEDUREBEGINEND是固定的
2)过程名:存储过程的名字。我们在调用的时候,就是使用CALL + 过程名调用。另外,尽量避免过程名跟Mysql已存在的函数名相同导致冲突
3)参数列表-参数类型:存储过程可以没有参数,也可以有多个参数,参数的声明是【参数名+参数类型】声明的。

使用示例:

CREATE PROCEDURE get_canteen_dish_sales ()
BEGINSELECT food_name, sales_weights FROM unify_dish_sales ORDER BY sales_weights DESC LIMIT 20;
END

2.2 调用存储过程

语法格式如下:

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

使用示例:

call get_canteen_dish_sales();

一个很简单的使用,查询的是我们生产库里面一个菜品分析表,获取菜品名称和销售量。

2.3 查看存储过程

语法格式如下:

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

使用示例:

select name from mysql.proc where db='unify-dev';
show PROCEDURE status;

2.4 删除存储过程

语法格式如下:

DROP PROCEDURE 过程名; # 删除的时候不要加小括号,直接给定存储过程的名字即可。
DROP PROCEDURE IF EXISTS 过程名; # 如果存储删除,不存在不删除并且不会报错

使用示例:

DROP PROCEDURE get_canteen_dish_sales;
DROP PROCEDURE IF EXISTS get_canteen_dish_sales;

三、存储过程中的语法构造

我们在最开始的时候介绍过,存储过程是可以编程的,意味着可以使用变量、表达式、控制语句来完成比较复杂的功能。接下来我们学习一下如何使用更丰富的语法来完成复杂的存储过程。

3.1 变量的声明以及赋值

变量的声明
变量声明的语法格式如下:

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

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

CREATE PROCEDURE calculate ()
BEGINDECLARE num1 INT;DECLARE num2 INT DEFAULT 1;SELECT num1 + num2;
END

PS:注意上面示例num1是没有默认值的,所以SELECT num1 + num2;是一个null值。

变量的赋值
变量的赋值有2种方式,分别为:SET赋值,以及SELECT INTO赋值。先来介绍下SET的赋值方式:

  • SET : 直接赋值使用SET关键字,可以赋常量或者是表达式,具体语法如下:
-- 注意:一次可以给多个变量赋值,中间使用逗号隔开。
SET 变量名 = 变量值 [,变量名 = 变量值] ...
  • 使用示例如下:
CREATE PROCEDURE calculate ()
BEGINDECLARE num1 INT;DECLARE num2 INT DEFAULT 1;SET num1=2,num2=3;SELECT num1 + num2;
END

再来看看SELECT INTO的赋值方式:

  • SELECT INTO:语法格式如下
SELECT <column | 聚合函数> INTO 变量名;
  • 使用示例:
CREATE PROCEDURE calculate ()
BEGINDECLARE num1 INT;DECLARE num2 INT DEFAULT 1;SELECT COUNT(1) INTO num1 FROM unify_dish_sales;SELECT num1+num2;
END

3.2 条件判断

if条件判断
语法格式如下:

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

使用示例:

CREATE PROCEDURE calculate ()
BEGINDECLARE openStatus VARCHAR(20);DECLARE storeTurnover DECIMAL(10, 2);SELECT turnover INTO storeTurnover FROM unify_report_store_line LIMIT 1;IF storeTurnover > 0THENSET openStatus='开业了';ELSESET openStatus='歇业中';END IF;SELECT openStatus;
END

上面的源码敢的事情如下:

  1. 声明了一个openStatus 变量,用来描述今天的营业装填
  2. 声明了storeTurnover 用来接收营业额
  3. 去数据库表查询营业额,由于我现在生产库营业额有多条记录,所以我用了个LIMIT 1限定只获取一条
  4. 判断storeTurnover ,如果大于0说明今天营业了;反之则没有

3.3 传递参数

传递参数需要在创建存储过程的时候,就要做好。语法格式如下:

CREATE PROCEDURE <过程名>([in/out/inout] 参数列表 参数类型)
BEGIN
<过程体 sql语句>
END

大家注意这个语法跟们最开始创建存储过程的时候,不同的是,参数列表前面的[in/out/inout],他们的作用分别如下:

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

使用示例1:in参数

CREATE PROCEDURE calculate (IN storeTurnover DECIMAL(10, 2))
BEGINDECLARE openStatus VARCHAR(20);IF storeTurnover > 0THENSET openStatus='开业了';ELSESET openStatus='歇业中';END IF;SELECT openStatus;
END

很简单的一个示例,改自前一个示例。之前是从数据库获取,现在是由用户自己定义。如果传入的数大于0,则返回开业了,反之返回歇业中。然后调用的时候,跟调用函数一样就可以了。

CALL calculate(0);

使用示例2:out参数

CREATE PROCEDURE calculate (IN storeTurnover DECIMAL(10, 2), OUT openStatus VARCHAR(20))
BEGINIF storeTurnover > 0THENSET openStatus='开业了';ELSESET openStatus='歇业中';END IF;SELECT openStatus;
END

调用的话,需要用一个Mysql的会话变量来接收,然后select

CALL calculate(0, @openStatus);
select @openStatus;

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

3.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;

使用示例:

CREATE PROCEDURE calculate (IN storeTurnover DECIMAL(10, 2), OUT openStatus VARCHAR(20))
BEGINCASE WHEN storeTurnover > 1000 THENSET openStatus='赚麻了';WHEN storeTurnover > 500 THENSET openStatus='小赚';ELSESET openStatus='亏了亏了';END CASE;
END

3.5 while循环

有条件的循环控制语句,当满足条件的时候进入循环,不满足条件的时候退出循环。语法结构如下:

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

使用示例:(计算从1加到n的值)

CREATE PROCEDURE pro_sum (IN num INT(11))
BEGINDECLARE number INT DEFAULT 0;DECLARE total INT DEFAULT 0;WHILE number <= num DOSET total = total + number;SET number = number + 1;END WHILE;SELECT total;
END

3.6 repeat循环

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

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

使用示例:(计算从1加到n的值)

CREATE PROCEDURE pro_sum (IN num INT(11))
BEGINDECLARE total INT DEFAULT 0;REPEAT set total = total + num;set num = num - 1;# 注意:这个 unti 后的查询条件不要加分号,加分号会报错。until num = 0END REPEAT;SELECT total;
END

3.7 loop循环与leave语句

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

[begin_label:] loopstatement_list
end loop [end_label]

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

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

上面两个结合起来的示例如下:

CREATE PROCEDURE pro_sum (IN num INT(11))
BEGINDECLARE total INT DEFAULT 0;mySum:loopset total = total + num;set num = num - 1;# 借助leave组织退出条件if num <= 0 thenleave mySum;end if; end loop mySum;SELECT total;
END

感谢

感谢小白教程的《Mysql教程》
感谢知乎大佬作者:程云博,的文章《MySQL高级篇——存储过程以及语法》

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

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

相关文章

CSS基础语法第二天

目录 一、复合选择器 1.1 后代选择器 1.2 子代选择器 1.3 并集选择器 1.4 交集选择器 1.4.1超链接伪类 二、CSS特性 2.1 继承性 2.2 层叠性 2.3 优先级 基础选择器 复合选择器-叠加 三、Emmet 写法 3.1HTML标签 3.2CSS 四、背景属性 4.1 背景图 4.2 平铺方式 …

CF505B Mr. Kitayuta‘s Colorful Graph

Mr. Kitayuta’s Colorful Graph 题面翻译 给出一个 n n n 个点&#xff0c; m m m 条边的无向图&#xff0c;每条边上是有颜色的。有 q q q 组询问 对于第 i i i 组询问&#xff0c;给出点对 u i , v i u_i,v_i ui​,vi​。求有多少种颜色 c c c 满足&#xff1a;有至…

【DRAM存储器九】SDRAM介绍-read、write、Precharge、DQM、Power down、Clock Suspend命令

&#x1f449;个人主页&#xff1a;highman110 &#x1f449;作者简介&#xff1a;一名硬件工程师&#xff0c;持续学习&#xff0c;不断记录&#xff0c;保持思考&#xff0c;输出干货内容 参考资料&#xff1a;《镁光SDRAM数据手册》、《PC SDRAM specification》 目录…

JUC第十三讲:JUC锁: ReentrantLock详解

JUC第十三讲&#xff1a;JUC锁: ReentrantLock详解 本文是JUC第十三讲&#xff0c;JUC锁&#xff1a;ReentrantLock详解。可重入锁 ReentrantLock 的底层是通过 AbstractQueuedSynchronizer 实现&#xff0c;所以先要学习上一章节 AbstractQueuedSynchronizer 详解。 文章目录 …

HTML的学习 Day02(列表、表格、表单)

文章目录 一、列表列表主要分为以下三种类型&#xff1a;1. 无序列表&#xff08;Unordered List&#xff09;&#xff1a;2. 有序列表&#xff08;Ordered List&#xff09;&#xff1a;将有序列表的数字改为字母或自定义内容li.../li 列表项标签中value属性&#xff0c;制定列…

MySQL 索引优化实践(单表)

目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…

考虑源荷不确定性的热电联供微网优化(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Blender 导出 fbx 到虚幻引擎中丢失材质!!!(使用Blender导出内嵌材质的fbx即可解决)

目录 0 引言1 Blender导出内嵌纹理的fbx模型 0 引言 我在Blender处理了一些fbx模型后再次导出到UE中就经常出现&#xff0c;材质空白的情况&#xff08;如下图所示&#xff09;&#xff0c;今天终于找到问题原因&#xff0c;记录下来&#xff0c;让大家避免踩坑。 其实原因很简…

Git使用【上】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析3 前言 先前有些git命令我在我的其它文章里面已经写过&#xff0c;若要查看可参考【Linu…

leetCode 55.跳跃游戏 贪心算法

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入…

安防视频/集中云存储平台EasyCVR(V3.3)部分通道显示离线该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

知识分享 钡铼网关功能介绍:使用SSLTLS 加密,保证MQTT通信安全

背景 为了使不同的设备或系统能够相互通信&#xff0c;让旧有系统和新的系统可以集成&#xff0c;通信更加灵活和可靠。以及将数据从不同的来源收集并传输到不同的目的地&#xff0c;实现数据的集中管理和分发。 通信网关完美克服了这一难题&#xff0c;485或者网口的设备能通过…

深度学习(1)---卷积神经网络(CNN)

文章目录 一、发展历史1.1 CNN简要说明1.2 猫的视觉实验1.3 新认知机1.4 LeNet-51.5 AlexNet 二、卷积层2.1 图像识别特点2.2 卷积运算2.3 卷积核2.4 填充和步长2.5 卷积计算公式2.6 多通道卷积 三、池化层 一、发展历史 1.1 CNN简要说明 1. 卷积神经网络&#xff08;Convolut…

PyCharm中使用pyqt5的方法2-2

1.2 是否下载成功 按照以上步骤安装了“pyqt5”、“pyqt5-tools”模块和“pyqt5designer”模块后&#xff0c;可以打开保存这三个模块的路径&#xff0c;找到其对应的文件夹&#xff0c;即可验证是否下载成功。 获取PyCharm保存下载模块路径的方法是&#xff0c;在PyCharm界面…

Sound/播放提示音, Haptics/触觉反馈, LocalNotification/本地通知 的使用

1. Sound 播放提示音 1.1 音频文件: tada.mp3&#xff0c; badum.mp3 1.2 文件位置截图: 1.3 实现 import AVKit/// 音频管理器 class SoundManager{// 单例对象 Singletonstatic let instance SoundManager()// 音频播放var player: AVAudioPlayer?enum SoundOption: Stri…

Linux系统编程系列之线程

一、什么是线程 线程&#xff08;Thread&#xff09;是计算机中的基本执行单元&#xff0c;是操作系统调度的最小单位。线程是进程内的一个独立执行流程&#xff0c;一个进程可以包含多个线程&#xff0c;这些线程共享进程的资源&#xff0c;但每个线程都有自己的独立栈空间以及…

挺进欧洲:中国汽车如何破解品牌与成本双重困境?

摘要&#xff1a;2022年&#xff0c;中国超越德国&#xff0c;跻身全球第二大汽车出口大国&#xff0c;仅次于日本。历经国内市场的激烈竞争和技术积累,中国汽车品牌凭借在新能源技术上的优势和制造力,决定挑战欧洲-BBA(奔驰、宝马、奥迪)的主场。令人惊讶的是,尽管在21世纪初,…

PCB放置过孔技巧

合理的放置过孔能有效的节约面积。 我们根据嘉立创的pcb工艺能力中写出单双面板最小过孔为0.3mm(内径)/0.5mm(外径) 设置过孔尺寸外直径为24mil&#xff08;0.61mm&#xff09;&#xff09;内直径为12mil&#xff08;0.305mm&#xff09; 嘉立创PCB工艺加工能力范围说明-嘉立…

扩容LVM卷导致lvm元数据丢失的恢复过程

一、问题描述 因某次MySQL binlog占用过高扩容时&#xff0c;是直接对云盘操作&#xff0c;而扩容直接操作了lvm卷而未操作云盘分区&#xff0c;并随后执行了扩容的partprobe&#xff0c;resize2fs卷等操作&#xff1b;最后&#xff0c;显示并未扩容成功&#xff0c;重启系统后…

基于YOLOv8的安全帽检测系统(2):Gold-YOLO,遥遥领先,助力行为检测 | 华为诺亚NeurIPS23

目录 1.Yolov8介绍 2.安全帽数据集介绍 3.Gold-YOLO 4.训练结果分析 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&#xff08;SOTA&#xff09;模型&#xff0c;它建立在先前YOLO成功基础上…