当前位置: 首页 > news >正文

【MySQL】存储过程与函数

一、存储过程

1、什么是存储过程

  • 它是一组经过预先编译的SQL的封装
  • 它被存储在MySQL服务器上,当需要执行它时,客户端只需要向服务器发出调用命令,就可以把这一系列预先存储好的SQL语句全部执行

2、存储过程的优缺点

  • 优点
    • 简化操作,一次编译多次使用,提高了sql语句的重用性
    • 直接调之前写好的SQL语句,减少出现失误的可能性
    • 减少了网络传输量,客户端只需要发出调用指令即可,不需要传输完整的SQL语句
    • 提高了安全性,减少了SQL语句在网络中暴露的风险,而且可以限制执行者权限
  • 缺点(阿里开发规范里面禁止使用存储过程,主要就是和第一二点有关)
    • 可移植性差,不可以跨数据库执行
    • 调试困难
    • 不适合高并发场景,高并发场景下需要减少数据库压力,有时数据库会采用分库分表的形式,而且对可扩展性要求很高,在这种情况下,存储过程会变得难以维护,增大了数据库的压力
    • 存储过程的版本管理很困难,假设数据库索引发生变化,可能导致存储过程失效

3、和视图、函数的差别

  • 视图是虚拟表,一般只负责查询数据,不会通过视图对底层数据表进行操作。而存储过程是专门存储程序化的SQL的,可以直接操作底层数据表
  • 函数是有返回值的,存储过程没有返回值,它只能将结果输出到某些OUT修饰的参数中

4、存储过程的创建

CREATE PROCEDURE 存储过程名称(IN|OUT|INOUT 参数名 参数类型,...)
[characteristics...]
BEGIN存储过程体
END

如何理解存储过程名称后面的形参列表

  • 没有跟形参列表:存储过程无参数无返回
  • 参数修饰符为IN:当前参数为入参,如果当前参数没有修饰符,那就默认是入参
  • 参数修饰符为OUT:当前参数为输出参数,当执行完存储过程之后,客户端可以读取这个参数的返回值
  • 参数修饰符为INOUT:当前参数既可以是入参也可以是输出参数

characteristics表示创建存储过程时指定的特性

characteristic:COMMENT 'string'| LANGUAGE SQL| [NOT] DETERMINISTIC| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }| SQL SECURITY { DEFINER | INVOKER }
  • LANGUAGE SQL:表明存储过程执行体所用语言是SQL
  • [NOT] DETERMINISTIC:入参相同时,如果存储过程执行后得到的结果不会发生改变。那么存储过程就是确定性的,即DETERMINISTIC。否则就是不确定性NOT DETERMINISTIC。在没有显式指定DETERMINISTIC的情况下,存储过程默认是不确定性NOT DETERMINISTIC
  • { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL的限制
    • CONTAINS SQL:当前存储过程的子程序包含SQL语句,但是不包含读写数据的SQL语句
    • NO SQL:当前存储过程的子程序不包含SQL语句
    • READS SQL DATA :当前存储过程的子程序包含读数据的SQL语句
    • MODIFIES SQL DATA :当前存储过程的子程序包含写数据的SQL语句
  • SQL SECURITY { DEFINER | INVOKER }:当前存储过程哪些用户可以执行。如果是DEFINER,就是只有创建者才能执行。INVOKER就是拥有访问权限的用户就可以执行
  • COMMENT string:注释信息,用于描述存储过程

5、使用DELIMITER设置新的结束标记
如果我们不将MySQL默认的语句结束符由;改为自定义的标记
那么下面的存储过程执行到SELECT语句结束后,就不会继续往下走了,这显然是错误的

所以我们在这里将$或者//定义为语句执行结束的标记
并且在执行完存储过程之后,再将结束标记改回;

DELIMITER $CREATE PROCEDURE SELECT_all_emp()
BEGINSELECT * FROM t_emp;
END $DELIMITER ;

6、存储过程的调用,使用关键字CALL
1)无参数类型的调用

DELIMITER $CREATE PROCEDURE select_AVG_salary()
BEGINSELECT AVG(salary) FROM t_emp;
END $DELIMITER $CALL select_AVG_salary();

2)带OUT类型的调用,注意输出变量的类型需要和表中字段的类型相同
假设我们要查询当前员工表中最低的工资,并且把将最低薪资通过参数ms输出

DELIMITER $CREATE PROCEDURE show_min_salary(OUT ms DOUBLE(8,2))
BEGINSELECT MIN(salary) INTO ms #使用INTO将最低薪资写入到ms变量FROM t_emp;
END $DELIMITER ;#调用,使用@自定义ms变量
CALLL show_min_salary(@ms);#查看此变量值
SELECT @ms;

3)带IN类型的调用,注意输入变量的类型需要和表中字段的类型相同
假设我们要查询当前员工表中某个员工的薪资,并使用IN参数empname输入员工姓名

DELIMITER $CREATE PROCEDURE show_someony_salary(IN empname VARCHAR(20))
BEGINSELECT salaryFROM t_emp WHERE last_name = empname;
END $DELIMITER ;# 调用方式一:直接传
CALL show_someony_salary('Decade');
# 调用方式二:定义变量,然后调用的时候传入变量
SET @name = 'Decade';
CALL show_someony_salary(@name);

4)带IN和OUT类型的调用
假设我们要查询当前员工表中某个员工的薪资,并使用IN参数empname输入员工姓名,使用OUT参数empsalary输出薪资

DELIMITER $CREATE PROCEDURE show_someone_salary2(IN empname VARCHAR(20),OUT empsalary DOUBLE(10,2))
BEGINSELECT salary FROM t_emp INTO empsalaryWHERE last_name = empname;
END $DELIMITER ;# 调用
CALL show_someone_salary2('Decade', @empsalary);
# 或者
SET @empname = 'Decade';
CALL show_someone_salary2(@empname, @empsalary);#查看此变量值
SELECT @empsalary;

5)带INOUT类型的调用

DELIMITER $CREATE PROCEDURE show_mgr_name(INOUT empname VARCHAR(20))
BEGINSELECT last_name INTO empnameFROM t_empwhere emp_id = (SELECT manager_id FROM t_empwhere last_name = empname);
END $DELIMITER ;# 调用
SET @empname = 'Decade';
CALL show_mgr_name(@empname);# 查看输出参数
SELECT @empname;

二、存储函数

前面已经学习过一些系统提供的函数,包括单行函数和聚合函数

1、存储函数的创建

CREATE FUNCTION 存储函数名称(参数名 参数类型,...)
RETURNS 返回值类型
[characteristics...]
BEGIN函数体 #函数体中肯定有 return语句
END
  • 存储函数的参数默认是IN类型的,也就是说它只有入参的说法
  • Returns Type是必须要有的,它指定了存储函数的返回值类型,函数体中必须要包含 return语句
  • characteristics的取值与上面存储过程的约束是一样的

2、使用SELECT进行存储函数的调用

SELECT 函数名(参数列表);

3、如果创建存储函数时,没有指明characteristics,可能会出现you *might* want to use the less safe log_bin_trust_function_creators variable这个报错,我们推荐以下两种方式进行解决

  • 方式一:加上必要的函数特性[NOT] DETERMINISTIC{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
DELIMITER $CREATE FUNCTION show_email_by_name()
RETURNS VARCHAR(20)DETERMINISTICCONTAINS SQLREADS SQL DATA
BEGINRETURN (SELECT eamil FROM t_emp WHERE last_name = 'Decade');
END $DELIMITER ;
  • 方式二:执行SET GLOBAL log_bin_trust_function_creators = 1;

4、存储函数也要用到DELIMITER,下面我们就了解一下存储函数的几种使用方式
1)不传参数

DELIMITER $CREATE FUNCTION show_email_by_name()
RETURNS VARCHAR(20)DETERMINISTICCONTAINS SQLREADS SQL DATA
BEGINRETURN (SELECT eamil FROM t_emp WHERE last_name = 'Decade');
END $DELIMITER ;# 调用存储函数
SELECT show_email_by_name();

2)传入参数

SET GLOBAL log_bin_trust_function_creators = 1;DELIMITER $CREATE FUNCTION show_email_by_name(empname VARCHAR(15))
RETURNS VARCHAR(20)
BEGINRETURN (SELECT eamil FROM t_emp WHERE last_name = empname);
END $DELIMITER ;# 调用存储函数
SELECT show_email_by_name('Decade');
# 或者
SET @empname = 'Decade';
SELECT show_email_by_name(@empname);

5、存储函数和存储过程的比较

  • 创建关键字:存储函数是FUNCTION,存储过程是PROCEDURE
  • 返回值:存储函数只有一个返回值,存储过程可以输出0个或者多个参数
  • 调用:存储函数用SELECT,存储过程用CALL
  • 使用场景:存储函数用于查询,存储过程用于更新数据
  • 存储函数可以放到查询语句中使用,存储过程不可以

三、存储过程、函数的查看、修改与删除

1、存储过程、函数的查看
1)查看存储过程和函数的创建信息

SHOW CREATE PROCEDURE 存储过程名称;SHOW CREATE FUNCTION 存储函数名称;

2)查看存储过程和函数的状态信息

SHOW PROCEDURE/FUNCTION STATUS; #会展示所有存储过程/函数SHOW PROCEDURE STATUS LIKE '%模糊查询%';
SHOW FUNCTION STATUS LIKE '%模糊查询%';

3)从information_schema.Routines查看存储过程和函数的状态信息

SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME = '存储过程名称' AND ROUTINE_TYPE = PROCEDURE;SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME = '存储函数名称' AND ROUTINE_TYPE = FUNCTION;

2、存储过程、函数的修改
存储过程、函数的修改不能修改过程体/函数体,只能通过ALTER对特性characteristics进行修改

ALTER PROCEDURE/FUNCTION 存储过程或者函数的名称 [characteristics...];

注意,只能修改以下特性

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

假设我们要修改上面的存储过程show_someone_salary2,修改执行权限和备注

ALTER PROCEDURE show_someone_salary2
SQL SECURITY INVOKER
COMMENT '测试修改';

3、存储过程、函数的删除

DROP PROCEDURE/FUNCTION IF EXISTS 存储过程/函数名称;

如有错误,欢迎指正!!!

相关文章:

【MySQL】存储过程与函数

一、存储过程 1、什么是存储过程 它是一组经过预先编译的SQL的封装它被存储在MySQL服务器上,当需要执行它时,客户端只需要向服务器发出调用命令,就可以把这一系列预先存储好的SQL语句全部执行 2、存储过程的优缺点 优点 简化操作&#xf…...

【数学】Pair of Topics—CF1324D

Pair of Topics—CF1324D 思路 很明显,需要对 a i a j > b i b j a_i a_j > b_i b_j ai​aj​>bi​bj​ 化简: a i − b i > b j − a j a_i - b_i > b_j - a_j ai​−bi​>bj​−aj​ a i − b i > − ( a j − b j ) a_…...

Qt文档阅读笔记-Fetch More Example解析

Fetch More Example这个例子说明了如何在视图模型上添加记录。 这个例子由一个对话框组成,在Directory的输入框中,可输入路径信息。应用程序会载入路径信息的文件信息等。不需要按回车键就能搜索。 当有大量数据时,需要对视图模型进行批量增…...

QtC++与QTableView详解

介绍 QTableView 是 Qt 框架中用于显示表格数据的视图控件,它是 QAbstractItemView 类的子类。QTableView 通常与 QStandardItemModel 或者自定义的数据模型一起使用,用于展示二维表格型数据。以下是对 QTableView 的详细讲解和在 Qt 中的作用&#xff…...

HG/T 6002-2022 氟树脂粉末涂料检测

氟树脂粉末涂料是指以三氟氯乙烯-乙烯基醚、四氟乙烯-乙烯基醚等交联型氟树脂或聚偏二氟乙烯PVDF树脂为主要成膜物质,可加入颜料、填料、助剂、固化剂等制成的粉末涂料,主要用于铝型材、幕墙金属板、家电等表面的装饰和保护。 HG/T 6002-2022 氟树脂粉末…...

【java】idea可以连接但看不到database相关的files

问题 idea右侧有database工具栏,但点击没有在recent files看到数据库相关文件 问题排查 点击 help-> show log in explorer查看日志 发现显示 2023-11-13 10:28:09,694 [1244376] INFO - #c.i.c.ComponentStoreImpl - Saving appDebuggerSettings took 22…...

信驰达科技加入车联网联盟(CCC),推进数字钥匙发展与应用

CCC)的会员。 图 1 深圳信驰达正式成为车联网联盟(CCC)会员 车联网联盟(CCC)是一个跨行业组织,致力于推动智能手机与汽车连接解决方案的技术发展。CCC涵盖了全球汽车和智能手机行业的大部分企业,拥有150多家成员公司。CCC成员公司包括智能手机和汽车制造…...

p9 Eureka-搭建eureka服务

1.在user-service项目引入spring-cloud-starter-netflix-eureka-client的依赖 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></depen…...

阶段七-Day01-SpringMVC

一、Sping MVC的介绍 1. 使用Front(前端)设计模式改写代码 1.1 目前我们的写法 目前我们所写的项目&#xff0c;持久层、业务层的类都放入到Spring容器之中了。他们之间需要注入非常方便&#xff0c;只需要通过Autowired注解即可。 但是由于Servlet整个生命周期都是被Tomca…...

Python---集合中的交集 、并集 | 与差集 - 特性

用 & 来求两个集合的交集&#xff1a;-----键盘上的7上的符号&#xff0c;shift 7 同时按 用 | 来求两个集合的并集&#xff1a; -----键盘上的7上的符号&#xff0c;shift 同时按&#xff08;就是enter键上面那个|\ &#xff09; 用 - 来求两个集合的差集&#xff…...

C++调用lua脚本,包括全局函数绑定、类绑定,十分钟快速掌握

系列文章目录 lua调用C/C的函数&#xff0c;十分钟快速掌握 C调用lua脚本&#xff0c;包括全局函数绑定、类绑定&#xff0c;十分钟快速掌握 系列文章目录摘要环境使用步骤码代码自定义函数多返回值变长参数 自定义类test_sol2.lua内容 程序输出 摘要 在这个快节奏的技术博客…...

快乐数[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 编写一个算法来判断一个数n是不是快乐数。「快乐数」定义为&#xff1a;对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为1&#xff0c;也可能是无限循环但始终变不到1。如…...

Spring源码阅读-ClassPathXmlApplicationContext

第一步&#xff1a;new一个ClassPathXmlApplicationContext对象 ClassPathXmlApplicationContext xmlContext new ClassPathXmlApplicationContext("mylearn.xml"); 第二步&#xff1a;调用构造方法 public ClassPathXmlApplicationContext(String configLocatio…...

考研分享第2期 | 中央财经大学管理科学跨考北大软微金融科技406分经验分享

一、个人信息 本科院校&#xff1a;中央财经大学 管理科学与工程学院 管理科学专业 上岸院校&#xff1a;北京大学 软件与微电子学院 金融科技专业硕士 考试科目&#xff1a; 初试&#xff1a;思想政治理论 英语一 数学二 经济学综合 面试考察范围广&#xff0c;包括英语自…...

Linux安装java jdk配置环境 方便查询

编辑/etc/profile文件&#xff1a; vim /etc/profile 在文件尾部添加如下配置&#xff1a; export JAVA_HOME/usr/local/jdk1.8.0_161/ export CLASSPATH.: J A V A H O M E / j r e / l i b / r t . j a r : JAVA_HOME/jre/lib/rt.jar: JAVAH​OME/jre/lib/rt.jar:JAVA_HOME/l…...

惊群效应之Nginx处理

文章目录 惊群概述Nginx 解决方案之锁的设计锁结构体原子锁创建原子锁获取原子锁实现原子锁释放 Nginx 解决方案之惊群效应总结&#xff1a; 惊群概述 在说nginx前&#xff0c;先来看看什么是“惊群”&#xff1f;简单说来&#xff0c;多线程/多进程&#xff08;linux下线程进…...

SpringBoot整合Ldap--超详细方法讲解

LADP概述 LDAP&#xff08;轻量目录访问协议&#xff09;是一种用于访问和维护分布式目录信息服务的协议。目录服务是一种存储和检索信息的服务&#xff0c;通常用于存储组织内的用户信息、组织结构、网络设备等数据。LDAP是一种轻量级的协议&#xff0c;设计用于在目录中进行查…...

【工程实践】Docker使用记录

前言 服务上线经常需要将服务搬到指定的服务器上&#xff0c;经常需要用到docker&#xff0c;记录工作中使用过dcoker指令。 1.写Dockerfile 1.1 全新镜像 FROM nvidia/cuda:11.7.1-devel-ubuntu22.04ENV WORKDIR/data/Qwen-14B-Chat WORKDIR $WORKDIR ADD . $WORKDIR/RUN ap…...

FreeSwitch安装视频

文章目录 序言Centos7安装FreeSwitch-1.6 序言 学习资料来源《FreeSWITCH权威指南》-作者杜金房这本书。我是2022年6月毕业的&#xff0c;偶然的机会接触到FreeSWITCH&#xff0c;FreeSWITCH纯属个人爱好&#xff0c;进行笔记整理。也一直希望有机会可以参与FreeSWITCH相关工作…...

SpringBoot3+Vue3+Mysql+Element Plus完成数据库存储blob类型图片,前端渲染后端传来的base64类型图片

前言 如果你的前后端分离项目采用SpringBoot3Vue3Element Plus&#xff0c;且在没有OSS&#xff08;对象存储&#xff09;的情况下&#xff0c;使用mysql读写图片&#xff08;可能不限于图片&#xff0c;待测试&#xff09;。 耗时三天&#xff0c;在踩了无数雷后&#xff0c…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...