Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL存储过程了解一下

MySQL存储过程了解一下

作者头像
布禾
发布于 2021-04-09 09:10:45
发布于 2021-04-09 09:10:45
1.4K00
代码可运行
举报
运行总次数:0
代码可运行
简介

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

存储过程的使用
创建存储过程

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE 存储过程名( IN|OUT|INOUT 参数名 数据类型 , ...)
BEGIN
	...
END;

MySQL存储过程的参数类型:

  1. IN,表示存储过程的输入参数,该参数的值将会传递给存储过程,在存储过程中可以对该参数进行修改,但是在存储过程返回时,该参数值不会被返回,相当于在存储过程中对该参数的修改对调用者来说是不可见的。
  2. OUT,表示存储过程的输入参数,该参数的值会在存储过程中初始化为NULL,当存储过程返回时,该值也会被返回,调用者可以看到被修改后的值。
  3. INOUT,表示存储过程的输入输出参数,该参数由调用者初始化,在存储过程中的做的任何更改都会被返回,调用者可以看到修改后的值。

存储过程创建示例:

创建存储过程student_procedure,student_procedure有一个输入参数age和一个输出参数num,查询tb_student表学生年龄大于等于输入参数age的人数,并将人数设置到num。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE student_procedure(IN age TINYINT, OUT num INT)
BEGIN
	SELECT COUNT(*) INTO num FROM tb_student t WHERE t.age>=age;
END;

MySQL命令行创建存储过程:

如果是在MySQL命令行创建存储过程,则需要临时的修改语句分隔符,因为MySQL默认语句分隔符是;,会使存储过程中的语句被直接解析而导致语法错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 设置//为语句分隔符
mysql> DELIMITER //

mysql> CREATE PROCEDURE student_procedure(IN age TINYINT, OUT num INT)
    -> BEGIN
    -> SELECT COUNT(*) INTO num FROM tb_student t WHERE t.age>=age;
    -> END;
    -> //
Query OK, 0 rows affected

--恢复为原来的分隔符
mysql> DELIMITER ;
调用存储过程

tb_student表数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+----+------+-----+-------------+-----------+----------+
| id | name | age | phone       | address   | class_id |
+----+------+-----+-------------+-----------+----------+
|  1 | 小明 |  18 | 188xxxx1234 | xxxxxxxxx |        1 |
|  2 | 小米 |  28 | 188xxxx1234 | xxxxxxxxx |        2 |
|  3 | 小看 |  28 | 188xxxx1234 | xxxxxxxxx |        3 |
|  4 | 小阿 |  38 | 188xxxx1234 | xxxxxxxxx |        3 |
|  5 | 小鬼 |  48 | 188xxxx1234 | xxxxxxxxx |        3 |
+----+------+-----+-------------+-----------+----------+

调用存储过程,查询年龄大于38的学生人数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 调用存储过程
mysql> CALL student_procedure(38, @num);
Query OK, 1 row affected

-- 查看返回结果
mysql> select @num;
+------+
| @num |
+------+
|    2 |
+------+
查看存储过程的定义

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SHOW CREATE PROCEDURE proc_name;

如查看student_procedure的定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SHOW CREATE PROCEDURE student_procedure;
+-------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Procedure         | sql_mode                                                       | Create Procedure                                                                                                                                                 | character_set_client | collation_connection | Database Collation |
+-------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| student_procedure | STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` PROCEDURE `student_procedure`(IN age TINYINT, OUT num INT) BEGIN SELECT COUNT(*) INTO num FROM tb_student t WHERE t.age>=age;END | utf8                 | utf8_general_ci      | utf8_general_ci    |
+-------------------+----------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
修改存储过程

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ALTER PROCEDURE proc_name [characteristic ...]

characteristic: {
    COMMENT 'string'
  | LANGUAGE SQL
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
}

ALTER PROCEDURE 语句用于修改存储过程的某些特征。如果要修改存储过程的内容,可以先删除原存储过程,再以相同的命名创建新的存储过程。

删除存储过程

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DROP PROCEDURE [ IF EXISTS ] proc_name

如删除student_procedure:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> DROP PROCEDURE student_procedure;
Query OK, 0 rows affected

mysql> CALL student_procedure(38, @num);
1305 - PROCEDURE student_procedure does not exist
流程控制语句
IF语句

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IF 判断条件 THEN 处理语句
    [ELSEIF 判断条件 THEN 处理语句]...
    [ELSE 处理语句]
END IF

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE test1(IN sex TINYINT)
BEGIN
	IF sex=1 THEN SET @sex='男';
	ELSEIF sex=0 THEN SET @sex='女';
	ELSE SET @sex='未知';
	END IF;
END;
CASE语句

CASE语句有两种写法:

语法1:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CASEWHEN1 THEN 处理语句
    [WHEN2 THEN 处理语句]...
    [ELSE 处理语句]
END CASE

语法2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CASE
    WHEN 条件判断 THEN 处理语句
    [WHEN 条件判断 THEN 处理语句] ...
    [ELSE 处理语句]
END CASE

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 写法1
CREATE PROCEDURE test2(IN sex TINYINT)
BEGIN
	CASE sex
	WHEN 1 THEN SET @sex='男';
	WHEN 0 THEN SET @sex='女';
	ELSE SET @sex='未知';
	END CASE;
END;

-- 写法2
CREATE PROCEDURE test3(IN sex TINYINT)
BEGIN
	CASE 
	WHEN sex=1 THEN SET @sex='男';
	WHEN sex=0 THEN SET @sex='女';
	ELSE SET @sex='未知';
	END CASE;
END;
LOOP语句

LOOP循环是一个死循环,一般情况需要配合LEAVE语句和ITERATE语句使用,LEAVE语句表示跳出该循环(类似Java中的break),ITERATE语句表示跳出本次循环(类似Java中的continue)。

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[别名:]LOOP
    处理逻辑
END LOOP [别名]

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE test4()
BEGIN
	SET @num=0;
	add_num:LOOP
		SET @num=@num+1;
		IF @num=10 THEN LEAVE add_num;
		END IF;
	END LOOP add_num;
END;
REPEAT语句

REPEAT语句是自带条件判断的循环语句,每次语句执行完毕后,会对条件进行判断,如果为true则退出循环,否则继续循环。(类似Java中的do while循环)

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[别名:] REPEAT
    处理语句
    UNTIL 条件判断
END REPEAT [别名]

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE test5()
BEGIN
	SET @num=0;
	add_num:REPEAT
		SET @num=@num+1;
		UNTIL @num=10 END REPEAT add_num;
END;
WHILE语句

WHILE语句也是自带条件判断的循环,和REPEAT语句的区别在于WHILE语句会先进行条件判断,当条件判断为true时才继续执行循环中的语句,为false则直接退出循环。(类似于Java中的while循环)

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[别名:] WHILE 条件判断 DO
    处理逻辑
END WHILE [别名]

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE test6()
BEGIN
	SET @num=0;
	add_num:WHILE @num<10 DO
		SET @num=@num+1;
		END WHILE add_num;
END;
游标

游标是用来逐行处理某个查询的结果集。

游标的声明必须出现在HANDLER声明之前声明,变量和条件声明之后声明

创建游标:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DECLARE 游标名称 CURSOR FOR sql查询;
打开游标:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
OPEN 游标名称;
使用游标:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FETCH 游标名称 INTO 变量1 [,变量2]...

将结果集中的数据保存到对应的变量当中去,游标第一次使用时默认读取结果集中的第一行,一般配合循环语句逐行处理整个结果集。

关闭游标:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CLOSE 游标名称;

CLOSE释放游标使用的所有内部内存和资源,因此每个游标不再需要时都应该关闭。游标关闭后不能使用,如果需要使用则需要重新打开游标。

示例

查询tb_student表,将所有学生名称连接成一个字符串设置到变量@name_Str中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE PROCEDURE test7()
BEGIN
	-- 声明局部变量student_name,用于接收数据集中的数据
	DECLARE student_name VARCHAR(10);
	-- 声明局部变量done,用于判断是否退出循环,默认值为FALSE
	DECLARE done INT DEFAULT FALSE;
	-- 声明游标my_cursor
	DECLARE my_cursor CURSOR FOR SELECT `name` FROM tb_student;
	-- 声明continue handler句柄,当出现SQLSTATE '02000'时将done设置为TRUE
	DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
	
	-- 设置用户变量@name_Str为空字符串
	SET @name_Str='';
	-- 打开游标
	OPEN my_cursor;
		-- 开始LOOP循环
		concat_name:LOOP
			-- 将数据集中的一行数据存放到指定的变量中
			FETCH my_cursor INTO student_name;
			-- 判断是否退出循环
			IF done THEN LEAVE concat_name;
			END IF;
			-- 连接学生名称字符串
			SET @name_Str = CONCAT(@name_Str,student_name);	
		END LOOP concat_name;
	-- 关闭游标	
	CLOSE my_cursor;
END;

结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> call test7();
Query OK, 0 rows affected

mysql> select @name_Str;
+----------------------+
| @name_Str            |
+----------------------+
| 小明小米小看小阿小鬼 |
+----------------------+
关于SQLSTATE '02000'

在使用游标时,可以通过FETCH将数据集中的数据保存到变量中进行处理,但是当整个数据集已经FETCH结束的时候,再去FETCH就会抛异常:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1329 - No data - zero rows fetched, selected, or processed

该异常对应的SQLSTATE为02000,所以需要指定句柄捕获这种异常情况来给标志赋值,后续就可以通过这个标志来判断数据集循环读取结束。

异常信息详见:Error Reference

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Mysql存储过程
存储过程就是一条或者多条SQL语句的集合,可以视为批文件。它可以定义批量插入的语句,也可以定义一个接收不同条件的SQL。
用户3467126
2019/08/29
7.2K0
Mysql高级7-存储过程
  存储过程是事先经过编译并存储在数据库中的一段sql语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。存储过程思想上很简单,就是数据库sql语言层面的代码封装与重用。
Se7eN_HOU
2023/08/15
8540
Mysql存储过程和存储函数
1.5.2. CASE - WHEN - THEN - ELSE - END CASE
爱撒谎的男孩
2019/12/31
2.1K0
【数据库原理与运用|MySQL】MySQL存储过程(详细超全)
云数据库https://cloud.tencent.com/product/cdb
小小程序员
2022/12/22
1.4K0
【数据库原理与运用|MySQL】MySQL存储过程(详细超全)
mysql存储过程菜鸟教程_mysql存储过程是什么
本文介绍关于在MySQL存储过程游标使用实例,包括简单游标使用与游标循环跳出等方法
全栈程序员站长
2022/11/10
4.9K0
Mysql之存储过程(下)
存储过程是由一组 SQL 语句构成的数据库对象,存储过程可以被存储在数据库中并在需要时执行。它支持控制流结构(如 IF 语句、CASE 语句、循环等),能够封装和重用数据库操作,提升代码的模块化和可维护性。
猫咪-9527
2025/04/29
1490
Mysql之存储过程(下)
MySQL 进阶之存储过程/存储函数/触发器
上面给大家演示了存储过程中的基本语法,现在只是在存储过程中定义了一条简单的select 语句 ,并没有任何逻辑。
叫我阿杰好了
2022/11/07
2.5K0
MySQL 进阶之存储过程/存储函数/触发器
MySQL自定义函数和存储过程
MySQL函数是一些具有特定功能的方法,在编写sql时,可以进行使用,从而完成对数据的处理。
半月无霜
2023/03/03
3.1K0
MySQL自定义函数和存储过程
MySQL的存储过程_MySQL创建存储过程
在项目开发中,经常会遇到这样一种场景,当修改A表的一条数据时,需要关联修改B表、C表甚至其他更多表的数据,为什么会这样呢?
全栈程序员站长
2022/11/08
23.6K0
MySQL的存储过程_MySQL创建存储过程
⑩⑤【DB】详解MySQL存储过程:变量、游标、存储函数、循环,判断语句、参数传递..
注意:用户定义的变量无需对其进行声明或初始化,不声明或初始化获取到的值为NULL。
.29.
2023/11/20
2.4K0
⑩⑤【DB】详解MySQL存储过程:变量、游标、存储函数、循环,判断语句、参数传递..
2024Mysql And Redis基础与进阶操作系列(9)作者——LJS[含MySQL存储过程之局部、系统变量、参数传递、流程控制-判断/case具体详步骤;注意点及常见报错问题所对应的解决方法]
存储过程就是一组SQL语句集,功能强大,可以实现一些比较复杂的逻辑功能,类似于 JAVA语言中的方法;
盛透侧视攻城狮
2024/10/22
2370
2024Mysql And Redis基础与进阶操作系列(9)作者——LJS[含MySQL存储过程之局部、系统变量、参数传递、流程控制-判断/case具体详步骤;注意点及常见报错问题所对应的解决方法]
MySQL 视图/存储过程/触发器
视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
用户9615083
2022/12/25
2.7K0
MySQL 视图/存储过程/触发器
《MySQL核心知识》第10章:自定义存储过程和函数
今天是《MySQL核心知识》专栏的第10章,今天为大家系统的讲讲MySQL中如何自定义存储过程和函数,希望通过本章节的学习,小伙伴们能够举一反三,彻底掌握MySQL中关于自定义存储过程和函数的知识。好了,开始今天的正题吧。
冰河
2022/12/01
3.7K0
《MySQL核心知识》第10章:自定义存储过程和函数
【MySQL高级】存储过程和函数
存储过程和函数是 事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
陶然同学
2023/02/24
1.1K0
【MySQL高级】存储过程和函数
【愚公系列】2023年03月 Java教学课程 103-MySQL数据库(存储过程和函数)
存储过程是一组预定义的SQL语句集合,它们被存储在数据库中并可以被重复调用。存储过程可以接收参数、执行一系列SQL操作并返回结果。
愚公搬代码
2023/03/28
1.2K0
【愚公系列】2022年01月 Mysql数据库-存储过程和函数
文章目录 一、MySQL存储过程和函数 1.存储过程和函数的概念 2.存储过程和函数的好处 3.存储过程和函数的区别 4.创建存储过程 5.调用存储过程 6.查看存储过程 7.删除存储过程 8.存储过程语法 8.1存储过程语法介绍 8.2变量的使用 8.3if语句的使用 8.4参数的传递 8.5case语句的使用 8.6while循环 8.7repeat循环 8.8loop循环 8.9游标 9.存储过程的总结 10.存储函数 一、MySQL存储过程和函数 1.存储过程和函数的概念 存储过程和函数是 事先经过
愚公搬代码
2022/01/28
7250
mysql存储过程之游标
 大多数SQL语句都是针对一个或多个表的单条语句。并非所有的操作都怎么简单。经常会有一个完整的操作需要多条才能完成
陈灬大灬海
2019/03/06
3K0
mysql存储过程之游标
MySQL/MariaDB 流程控制语句
本文目录: 1.BEGIN...END 2.true和false 3.if结构 4.case结构 5.loop、leave和iterate 6.repeat循环 7.while循环
星哥玩云
2022/08/16
9330
mysql存储过程
CONCAT(person_no,"号犯人住", i , "号床位"); ---字符串拼接
用户5927264
2019/07/31
8.6K0
浅谈 MySQL 存储过程与函数
存储过程 和 存储函数说实话本人工作中不经常使用,康师傅也说 阿里开发准则 不建议使用存储过程/函数… 但这并不是咱不会的理由🙃
Java_慈祥
2024/08/06
3320
浅谈 MySQL 存储过程与函数
推荐阅读
相关推荐
Mysql存储过程
更多 >
LV.1
这个人很懒,什么都没有留下~
作者相关精选
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验