【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 存储过程/函数名称;

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

密钥安全存储方案探讨与实践

随着信息技术的迅猛发展和应用范围的不断扩大,我们日常生活中的许多方面已经与信息技术密不可分。而在信息安全领域中,密钥的安全存储显得尤为重要。本文将探讨密钥安全存储的必要性、相关技术和实践方案,并提出一些解决方案。 一、密钥安全存…

IDEA 部署服务到 Docker 容器

第一步,配置Docker启用远程tcp端口,并重新启动 假设已经安装了Docker,编辑Docker启动服务脚本 [tobbcolocalhost ~]$ sudo vim /usr/lib/systemd/system/docker.service在ExecStart配置末尾增加-H tcp://0.0.0.0:2375 -H unix://var/run/dock…

数据结构 1、基本概念 动态数组实现

一、大O表示法 判断一个算法的效率 难点 二、线性表 1.定义 2.数学定义 线性表是具有相同类型的n(n>0)个数据元素的有限序列(a0,a1,a2,...,an),ai是表项,n是表长度 3.性质 4.线性表的基本操作 1.创建线性表 2…

微软允许OEM对Win10不提供关闭Secure Boot

用户可能将无法在Windows 10电脑上安装其它操作系统了,微软不再要求OEM在UEFI 中提供的“关闭 Secure Boot”的选项。 微软最早是在Designed for Windows 8认证时要求OEM的产品必须支持UEFI Secure Boot。Secure Boot 被设计用来防止恶意程序悄悄潜入到引导进程。问…

论文精读 MediaPipe BlazeFace

BlazeFace:Sub-millisecond Neural Face Detection on Mobile GPUs BlazeFace:基于移动GPUs的亚毫秒神经人脸检测 论文地址:arxiv.org/pdf/1907.05047.pdf 源码地址:GitHub - tkat0/PyTorch_BlazeFace: Unofficial PyTorch implementation…

【OpenVINO】基于 OpenVINO C# API 部署 RT-DETR 模型

基于 OpenVINO C# API 部署 RT-DETR 模型 1. RT-DETR2. OpenVINO3. 环境配置4. 模型下载与转换5. C#代码实现5.1 模型推理类实现1. 模型推理类初始化2. 图片预测API 5.2 模型数据处理类RTDETRProcess1. 定义RTDETRProcess2. 输入数据处理方法3. 预测结果数据处理方法 6. 预测结…

【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV1)模型算法详解

【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV1)模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV1)模型算法详解前言GoogLeNet(InceptionV1)讲解Inception结构InceptionV1结构1x1卷积的作用辅助分类器 GoogLeNet(Inceptio…

算法通关村第十六关青铜挑战——原来滑动窗口如此简单!

大家好,我是怒码少年小码。 从本篇开始,我们就要开始算法的新篇章了——四大思想:滑动窗口、贪心、回溯、动态规划。现在,向我们迎面走来的是——滑动窗口思想!😝 滑动窗口思想 概念 在数组双指针里&am…

虚拟化服务器+华为防火墙+kiwi_syslog访问留痕

一、适用场景 1、大中型企业需要对接入用户的访问进行记录时,以前用3CDaemon时,只能用于小型网络当中,记录的数据量太大时,本例采用破解版的kiwi_syslog。 2、当网监、公安查到有非法访问时,可提供基于五元组的外网访…

SPI协议详解

SPI协议详解 文章目录 SPI协议详解前言一、SPI是什么?二、通信原理SPI 通信的 4 种工作模式 总结 前言 好久没写这种协议了,最近正好需要用到,便详细的复习一下。 一、SPI是什么? SPI是串行外设接口(Serial Periphe…

Android studio2022.3项目中,如何去除底部导航菜单项被点击时的点击反馈效果(涟漪效果)

如果使用bottomNavigationView.setItemBackgroundResource(0)来去除底部导航菜单点击反馈效果不生效,可能是由于其它样式或主题的影响。 在这种情况下,可以通过自定义选择器(selector)来设置底部导航菜单项的背景。 首先&#x…

Spring-动态代理

动态代理 代理模式:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。 动态代理可以在不修改类源码的前提下,给类中方法增加额外逻辑 通过cglib来实现的代理对象的创建: 基于…

MES系统如何赋能制造企业实现4M防错追溯?

生产过程4M管理和MES系统的结合是现代制造业中关键的质量管理实践,它有助于提高生产效率、降低生产成本并保证产品质量。本文将深入探讨4M管理的概念,以及MES系统如何赋能制造企业实现4M防错追溯。 一、4M管理的概念 4M管理是指在制造过程中管理和控制四…

浅谈数据结构之递归

1. 递归的定义 递归是一种在解决问题时使用自身的特殊方法。在计算机科学和数据结构中,递归是一种通过将问题分解成更小的、相似的子问题来解决复杂问题的方法。递归可以直接或间接地调用自身,将大问题转化为规模较小的子问题,直到达到基本情…

leetCode 92.反转链表 II + 图解

92. 反转链表 II - 力扣&#xff08;LeetCode&#xff09; 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 206. 反转链表 - 力扣&#xff08;LeetCode&am…

区块链链游合约系统开发项目模式技术方案

​随着区块链技术的发展&#xff0c;链游合约系统开发逐渐成为了一个备受关注的项目。本文将探讨区块链链游合约系统开发项目的技术方案&#xff0c;包括项目背景、开发目标、技术架构、系统流程、安全措施等方面的内容。 一、项目背景 链游是一种基于区块链技术的游戏&#xf…

加密磁盘密钥设置方案浅析 — LUKS1

虚拟化加密磁盘密钥设置方案浅析 前言元数据分析元数据格式整体格式头部格式加密算法密码校验key slot格式其它字段 流程验证 前言 我们在虚拟化加密磁盘密钥设置方案浅析 — TKS1中介绍了加密磁盘密钥设置方案&#xff0c;TKS1对密钥设置(Linux Unified Key Setup)的流程和方…

阿里云容器镜像服务的运维总结

一、背景 容器镜像服务&#xff0c;作为一个可选付费产品&#xff0c;主要作用是存储docker的镜像仓库&#xff0c;供k8s拉取到Pod节点里。 你可以自己搭建一个harbor镜像仓库&#xff0c;在公司的开发环境下&#xff0c;将image推送到仓库&#xff1b;然后在生产k8s从仓库拉取…

7-5 计算每个学生的平均成绩

7-5 计算每个学生的平均成绩 分数 15 作者 殷伟凤 单位 浙江传媒学院 输入所有学生的姓名和成绩&#xff0c;以#结束。输出每个学生的平均成绩表。 输入格式: 每一行输入一个学生的姓名和成绩&#xff0c;以空格分隔。 输入完成后以#结束 输出格式: 每行显示一个学生的姓名和…

QtC++与QTreeView详解

介绍 QTreeView 是 Qt 框架中的一个视图控件&#xff0c;用于显示树形结构的数据。它是 QAbstractItemView 类的子类&#xff0c;通常与数据模型结合使用。以下是 QTreeView 的详细讲解和在 Qt 中的作用&#xff1a; QTreeView 的作用&#xff1a; 显示层次数据&#xff1a; …