关于对【mysql存储过程】的理解与简述

这篇具有很好参考价值的文章主要介绍了关于对【mysql存储过程】的理解与简述。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/130857854
出自【进步*于辰的博客】

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

1、概述

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

1、优点

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

2、缺点

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

3、补充说明

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

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

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

2、关于存储过程的使用

2.1 操作

工具:navicat。
关于对【mysql存储过程】的理解与简述
关于对【mysql存储过程】的理解与简述
关于对【mysql存储过程】的理解与简述
关于对【mysql存储过程】的理解与简述
所有存储过程存储于数据表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 参数模式 \color{green}{参数模式} 参数模式,用于声明此参数是否可用于传入 / 传出,默认为in
    in表示输入参数,限制参数只能用于传入,即形参out表示输出参数,限制只能用于传出,即返回值
    第3种参数模式:inout,表示此参数既可传入,也可传出(具体如何使用,后续补充)。
  5. 参数最好不要与字段名称相同;
  6. 存储过程体必须用begin...end囊括;
  7. 每行必须以“;”(分号)结尾;
  8. 任何参数,若未初始化(设置默认值),则当将此参数作为返回值时(即select 参数),此存储过程无结果。当然,select后也可是常量;
  9. 语句体(SQL语句)不能嵌套流程控制语句,如:if、loop;
  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 概述

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

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

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,结束循环)。

4、最后

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

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

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

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

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

本文完结。文章来源地址https://www.toymoban.com/news/detail-471192.html

到了这里,关于关于对【mysql存储过程】的理解与简述的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 011:Mapbox GL两种方式隐藏logo和版权,个性化版权的声明

    第011个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中用两种方式隐藏logo和版权,并个性化版权的声明 。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 示例效果

    2023年04月17日
    浏览(55)
  • 关于二进制的原码、补码和反码,以及表示范围、常见位运算符和进制转换的理解与简述

    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/17963363 出自【进步*于辰的博客】 参考笔记一,P3.13、P5.1;笔记三,P43.1/3、P44.1。 注:我暂且没有整理关于二进制、原码、补码和反码等概念的理论,本文中的阐述都基于

    2024年02月02日
    浏览(46)
  • Mysql 存储过程 / 存储函数

    目录 0 课程视频 1 基本语法 1.0 作用 -在数据库中 封装sql语句 - 复用 - 减少网络交互 -可接收参数返回数据 1.1 创建 1.2 调用 1.3 查看 1.4 删除 1.5 ; 封号结束符 改成 $$ 双刀符合结束语句 - 因为打包封号结束有冲突 1.6 在cmd 中定义 存储过程 打包的事务 - 打包完 可以改回 封号  

    2024年02月01日
    浏览(55)
  • MySQL(视图,存储函数,存储过程)

    作业1:  作业实现: 首先创建学生表,课程表,以及学生选课表。  1.用SQL语句创建学生表student,定义主键,姓名不能重名,性别只能输入男或女,所在系的默认值是 “计算机”。 2.修改student 表中年龄(age)字段属性,数据类型由int 改变为smallint。 3.为SC表建立按学号(

    2024年01月21日
    浏览(46)
  • MySQL——存储过程与存储函数

    MySQL从 5.0版本 开始支持 存储过程 和 存储函数 。存储过程和函数能够将复杂的SQL逻辑封装在一起,应用程序无须关注存储过程和函数内部复杂的SQL逻辑,而只需要简单地调用存储过程和函数即可。 1.1 理解 含义 :存储过程的英文是 Stored Procedure 。它的思想很简单,就是一组

    2024年02月10日
    浏览(44)
  • 【MySQL速通篇003】MySQL视图,MySQL触发器,MySQL函数,MySQL存储过程(参数分类,存储过程的增删改查等),SQL的动态执行,支持事务的存储过程,pymysql

    这篇万字博客主要包括了我对: MySQL视图,MySQL触发器,MySQL函数,MySQL存储过程(参数分类,存储过程的增删改查等),SQL的动态执行,支持事务的存储过程,pymysql等的总结,可谓非常的详细😃 文章毕竟这么长,对于文章中的一些语法,概念,例子等错误,欢迎并感谢各位读

    2023年04月27日
    浏览(79)
  • MySQL之存储过程和存储函数

    能够将完成特定功能的SQL指令进行封装(SQL指令集),编译之后存储在数据库服务器上,并且为之取一个名字,客户端可以通过名字直接调用这个SQL指令集,获取执行结果。 2.1 优点 (1)SQL指令无需经客户端编写通过网络传送,可以节省网络开销,同时避免使用SQL指令在网络传

    2024年02月05日
    浏览(50)
  • MySQL存储函数与存储过程习题

    创建表并插入数据: 1、创建一个可以统计表格内记录条数的存储函数 ,函数名为count_sch() 先创建一个表并插入一些数据: mysql d // mysql create function count_sch() - returns int - begin - declare i int default 0; - select count(*) into i from sch; - return i; - end // Query OK, 0 rows affected (0.00 sec) mysql sel

    2024年01月19日
    浏览(46)
  • 【MySql】MySql存储过程与函数

    存储过程没有返回值,函数有返回值 存储过程就是一组预先编译好的SQL语句的封装,需要执行时客户端向服务器发送调用请求,服务器就会将这一系列预先存储好的SQL语句全部执行。 简单举例:存储过程的创建 DELIMITER意味将$设置为结束标识,这样就可以在存储过程中使用分

    2024年02月09日
    浏览(43)
  • MySQL高级-存储引擎+存储过程+索引(详解01)

    目录 1.mysql体系结构  2.存储引擎 2.1.存储引擎概述 2.2.1.InnoDB 2.2.2.MyISAM 2.2.3.存储引擎选择 3.存储过程 3.1.存储过程和函数概述  3.2.创建存储过程 3.3.调用存储过程 3.4.查看存储过程 3.5.删除存储过程 3.6.语法 3.6.1.变量 3.6.2.if条件判断 3.6.3.传递参数 3.6.4.case结构 3.6.5.while循环 3.

    2024年02月13日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包