首页 > 数据库 >[MySQL]存储过程

[MySQL]存储过程

时间:2024-04-05 12:45:57浏览次数:30  
标签:语句 存储 示例 游标 MySQL rComId 过程

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://www.cnblogs.com/cnb-yuchen/p/18032044
出自【进步*于辰的博客

存储过程的细节很多,而在实际工作中又未必都能涉及这些细节,工作时间一长,就可能忘记,于是特来写这篇文章,既是为自己做个笔记,也是跟大家分享存储过程的学习和使用方法。
参考笔记三,P34.1、P35、P37.1。

目录

1、概述

“存储过程”是一种存储于数据库、封装了SQL语句和流程控制语句、进而通过类似“方法调用”的形式来调用(如:传参、获取返回值)、从而实现业务功能(即将一定程序业务迁移到数据库内,将业务交由数据库管理)的数据结构。

优点:

  1. 存储过程对复杂的SQL语句进行了封装,而调用简便,故简化了一些复杂的操作(如:业务逻辑)。
  2. 简化了对变动的管理
    若数据表变动(如:表名、字段名修改)或业务变动,不需要变动代码。
  3. 提高了程序性能
    因为存储过程存储于数据库,减少了SQL传输的流量(一般会用到存储过程的SQL语句都很长,几十上百行)。并且,数据库会在调用时对存储过程进行编译。大多数数据库(如:Oracle、MySQL)中,编译后的存储过程存储于数据库缓存,其中,MySQL存储过程是“按需编译”。
    若存储过程在单个连接中被多次调用,调用的就是缓存内的存储过程,进一步提高了查询速度;否则会先对存储过程进行编译,此时存储过程的执行效率相当于查询。
  4. 存储过程提供了一个接口供开发人员调用,这使得开发人员不必考虑其内部细节。同时,只需向访问存储过程的应用程序授权,而不必为其提供基础数据表权限,故提高了安全性,且可重用和透明。

缺点:

  1. 存储过程会占用当前连接内存
    因为存储过程经过编译存储于缓存中,而缓存是内存的一部分。其中,由于MySQL设计的初衷是“高效的查询,非逻辑运算”,故若存储过程中使用了大量的逻辑操作则会占用大量的CPU。
  2. 存储过程的结构使得开发复杂的存储过程变得困难。
  3. 存储过程难以调试(仅有很少的工具可以调试存储过程),使得开发和维护都不容易。
  4. 对数据库的依赖性高,难以移植(存储过程的内部就是SQL语句,自然对数据库依赖性高)。

补充说明:

关于流程控制语句,可查阅博文《[MySQL]流程控制语句》。

大都是情况下,存储过程内都会包含流程控制语句。为何?因为使用存储过程的原因无非两种:

  1. 封装一条复杂的SQL语句(往往是一个事务)。
  2. 封装多个原子操作(SQL语句),而这些原子操作间会进行一些逻辑运算或数据处理。

2、存储过程的使用

2.1 可视化操作(navicat)

工具:navicat。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所有存储过程存储于数据表information_schema.routines中。

2.2 示例

员工表:emp

字段名 类型 说明
emp_no smallint 员工号
emp_name varchar(20) 员工名
emp_salary decimal(5,2) 员工工资

先看示例:

CREATE DEFINER=`root`@`localhost` PROCEDURE `P_admin_EIByENo_Sel`(IN `empNo` int,OUT `empName` varchar(20))
BEGIN
	
	// 定义变量 doubleSal,表示“双倍工资”,默认值为0,定义默认值也可以是 default(0)
	declare doubleSal int default 0;
	
	// 查询员工号为empNo的员工的工资,并将值赋予变量 doubleSal
	select emp_salary into doubleSal from emp where emp_no = empNo;
	
	set doubleSal = doubleSal * 2;// 赋值,必须使用 set。注意:此处不兼容:*=/+=
	
	// 查询工资是此员工工资双倍的员工名
	select emp_name into empName from emp where emp_salary = doubleSal;
	
	select empName;// 这是固定格式,相当于”result 变量“
	
END

示例说明 + 注意事项:

  1. 创建存储过程格式:create procedure 存储过程名(参数列表) begin...end。(示例中definer...语句是指明用户、连接、数据库等)
  2. 存储过程名不能包含“-”(连字符)。
  3. 存储过程命名规范:P_[前/后台标识]_[模块/功能简称]By[条件名简称]_Sel(Sel表示查询,Del表示删除...)
  4. 在参数empNo、empName前的in/out参数模式,用于声明此参数是否可用于传入 / 传出,默认为in
    in表示输入参数,限制参数只能用于传入,即形参out表示输出参数,限制只能用于传出,即返回值
    第3种参数模式:inout,表示此参数既可传入,也可传出(具体如何使用,后续补充)。
  5. 参数最好不要与字段名称相同。
  6. 存储过程体必须用begin...end囊括。
  7. 每行必须以“;”(分号)结尾。
  8. 任何参数,若未初始化(设置默认值),则当将此参数作为返回值时(即select 参数),此存储过程无结果。当然,select后也可是常量。
  9. 语句体(SQL语句)不能嵌套流程控制语句,如:ifloop
  10. 所有的定义(declare)必须置于开头,且变量或条件的定义要在游标(cursor)的定义之前;

2.4 调用

call P_admin_EIByENo_Sel(1001, @);

这是固定格式,无论是在navicat命令行、cmd,还是在程序中。

1001对应传入参数empNo@对应传出参数empName,也可以是@empName@xx,就目前我所知,@后的标识任意(存储过程的返回值由select 变量决定,与@后的标识无关,但传出参数empName的位置必须至少有一个@(相当于占位符)。

存储过程的实参与Java方法实参有一定类似,即赋值类型限制。如示例,可以是1001,而不能是'1001'(字符型)。

3、cursor(游标)

3.1 介绍

什么是游标?
“游标”是一种能够对结果集中的每一行记录进行定位、并对所指向记录的数据进行操作的数据结构。
如:Java迭代器(iterator)中的也是游标,也称之为“光标”,其初始指向第一个元素的前面,即-1

游标的用途是什么?
迭代器有何用途?遍历。因此,存储过程中的游标是用于控制遍历,或者说用于在循环中获取记录。

3.2 示例

功能:根据用户ID,删除评论和评论回复记录。

CREATE DEFINER=`root`@`localhost` PROCEDURE `P_admin_RRTUByUid_Del`(in userId int)
BEGIN
	
	declare rComId int default 0;// 评论ID
	declare rRepN int default 0;// 评论回复数
	
	// 定义游标
	declare rComId_cursor cursor for 
		select comment_id from gd_resource_comment where user_id = userId;// 根据用户ID查询所有评论ID
	
	declare rComId_next int default 0;
	declare continue handler for not found set rComId_next = -1;// -- -A

	open rComId_cursor;// 打开游标
	getRComId:loop
		// 从结果集中获取一行记录。结合上下文,此结果集是当前用户旗下的所有评论ID,
		// 因此每次获取(fetch)的是其中一个评论ID
		fetch rComId_cursor into rComId;
		
		// 查询当前评论ID(rComId)所对应的评论回复数
		select count(1) into rRepN from gd_resource_response where comment_id = rComId;
		if rRepN > 0 then
			delete from gd_resource_response where comment_id = rComId;// 删除评论回复
		end if;
		delete from gd_resource_comment where comment_id = rComId;// 删除评论
		
		if rComId_next = -1 then// --------------------------------------B
			leave getRComId;// 跳出循环,类似 break
		end if;
	end loop getRComId;
	close rComId_cursor;// 关闭游标
	
END

示例说明 + 注意事项:

  1. 游标定义格式:declare 游标名 cursor for select_statement。(其中的select_statement是查询型SQL语句)
  2. 游标使用(fetch)前需要先打开(open 游标名),游标打开时如iterator的游标一般,初始指向第一行的前面。使用完后(循环结束)最好关闭游标(close 游标名)。其中,游标可多次打开(可用于多个循环)。
  3. 获取游标值(一行记录):fetch 游标名 into 变量
  4. 示例中 A 的作用。
    大家肯定用过Java迭代器,当调用next()时,在底层会先判断是否存在下一个元素,若存在,则返回此元素;否则返回null,不会出现异常。
    而在cursor中,当fetch时,同样会先判断是否存在下一行记录,若存在则返回此记录,否则报错。(A 的作用就是避免报错)
    实现思路: 先判断是否存在下一行记录,若不存在则跳出循环,避免下一次fetch
    具体实现: 定义 A,格式:declare continue handler for not found set 变量 = 值。什么意思呢?就是当fetch时,A 也会执行,若满足not found(即不存在下一行记录)时,执行变量 = 值。那么,就可以使用此变量来控制循环(示例中 B,结束循环)。

最后

本文中的例子是为了方便大家理解、便于阐述存储过程而简单举出或是我曾用过的,不一定有实用性。

其实存储过程的细节很多,只是我没有那么细致地一一进行阐述。我阐述的原则是“以吾之理解,着重之阐述”。因此,这篇文章可能并不适合 0 基础。

给大家推荐两篇博文(转发),这是我系统学习MySQL存储过程时参考的文章。

  1. MySQL中的存储过程(详细篇)
  2. Mysql存储过程大全

如果大家想要快速掌握这个知识点,我的建议是“多测试,学以致用”。

本文完结。

标签:语句,存储,示例,游标,MySQL,rComId,过程
From: https://www.cnblogs.com/cnb-yuchen/p/18032044

相关文章

  • java计算机毕业设计(附源码)影院订票app(ssm+mysql+maven+LW文档)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在数字化时代,人们对于娱乐消费的方式和习惯正在发生着翻天覆地的变化。随着智能手机的普及以及移动互联网技术的飞速发展,线上订票系统成为了人们生活中不......
  • java计算机毕业设计(附源码)影视创作论坛系统(ssm+mysql+maven+LW文档)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着科技的不断进步和互联网的普及,影视创作行业也在经历着前所未有的变革。传统的影视创作模式已经无法满足现代社会的需求,而新兴的影视创作论坛系统则应......
  • java计算机毕业设计(附源码)影视游戏推广系统(ssm+mysql+maven+LW文档)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着数字媒体时代的到来,影视和游戏产业迎来了前所未有的发展机遇。影视作品以其生动的叙事和视听效果吸引着全球观众,而游戏则以其互动性和沉浸式体验成为......
  • 回归预测 | Matlab基于CPO-GPR基于冠豪猪算法优化高斯过程回归的多输入单输出回归预测
    回归预测|Matlab基于CPO-GPR基于冠豪猪算法优化高斯过程回归的多输入单输出回归预测目录回归预测|Matlab基于CPO-GPR基于冠豪猪算法优化高斯过程回归的多输入单输出回归预测预测效果基本介绍程序设计参考资料预测效果基本介绍Matlab基于CPO-GPR基于......
  • 在Linux中,挂载和卸载文件系统过程是什么?
    在Linux中,挂载和卸载文件系统是系统管理中常见的操作,用于访问和管理存储设备上的数据。以下是挂载和卸载文件系统的基本过程:1.挂载文件系统过程:准备挂载点:在Linux系统中,挂载文件系统需要一个挂载点,这是一个空目录,充当存储设备和Linux文件系统之间的桥梁。首先,创建或选择一个......
  • 基于SSM+Jsp+Mysql的超市管理系统
    开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9系统展示管理员登录员工管理商品类型管理商品库存管理商品进货管理上班打卡管理请假信息管理交流信息......
  • 【附源码】计算机毕业设计智慧社区团购系统的设计(java+springboot+mysql+mybatis+论文
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义随着互联网技术的发展和普及,社区团购作为一种新兴的电商模式,正逐渐改变着人们的购物习惯。然而,传统的社区团购系统存在着一些问题,如信息不透明、效率低下、用户体......
  • 【附源码】计算机毕业设计游戏分享网站(java+springboot+mysql+mybatis+论文)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义随着互联网技术的发展,游戏行业正逐渐向数字化、网络化方向发展。越来越多的游戏玩家开始通过网络分享自己的游戏心得、攻略和视频等内容,形成了一个庞大的游戏分享......
  • 【附源码】计算机毕业设计在线药品销售系统(java+springboot+mysql+mybatis+论文)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义随着互联网技术的不断发展,人们的生活方式也在逐渐改变。在药品销售领域,传统的线下药店已经不能满足人们的需求。在线药品销售系统应运而生,为人们提供了一个更加便......
  • Mysql主从复制实战(1主3从)
    文章目录主从复制实现原理主从复制的优点主从复制的分类实现1主3从的架构验证主从复制主从复制MySQL主从复制是一种数据库复制技术,它允许一个MySQL数据库服务器将数据更新操作(增删改)自动复制到一个或多个其他从数据库服务器。这种技术可以提高数据库的可用性、扩......