【MySql】MySql存储过程与函数

news/2025/2/11 13:10:06/

存储过程与函数

存储过程没有返回值,函数有返回值

存储过程

存储过程就是一组预先编译好的SQL语句的封装,需要执行时客户端向服务器发送调用请求,服务器就会将这一系列预先存储好的SQL语句全部执行。

简单举例:存储过程的创建

DELIMITER意味将$设置为结束标识,这样就可以在存储过程中使用分号进行分隔了,但注意要在末尾改回来

DELIMITER $
CREATE PROCEDURE select_all_data()
BEGINSELECT * FROM employees;
END $delimiter ;

调用存储过程:

CALL select_all_data();

求平均值的存储过程:

DELIMITER //
CREATE PROCEDURE avg_employee_salary()
BEGINSELECT AVG(salary) AS avg_salary FROM employees;
END //
DELIMITER ;CALL avg_employee_salary();

求最大值的存储过程:

DELIMITER $
CREATE PROCEDURE show_max_salary()
BEGINSELECT MAX(salary)FROM employees;
END $
DELIMITER ;CALL show_max_salary()

带IN、OUT、INOUT的存储过程

查看最低薪资并将其输出

# 查询工资最低并将其保存到ms变量中并输出
DELIMITER $
CREATE PROCEDURE show_min_salary(OUT ms DOUBLE)
BEGINSELECT MIN(salary) INTO msFROM employees;
END $
DELIMITER ;# 调用该函数
CALL show_min_salary(@temp);# 调用变量
SELECT @temp;

查询某个员工的薪资

# 查询某个员工的薪资(使用IN作为形参传入值)
DELIMITER $
CREATE PROCEDURE show_someone_salary(IN empname VARCHAR(20))
BEGINSELECT salary FROM employees WHERE last_name = empname;
END $
DELIMITER ;# 调用
CALL show_someone_salary('Abel');# 或者这样调用
SET @empname := 'Abel';
CALL show_someone_salary(@empname);

查询某个员工的薪资,传入员工名称,传出员工薪资

# 查询某个员工的薪资,传入员工名称,传出员工薪资
DELIMITER //
CREATE PROCEDURE show_someone_salary2(IN empname Varchar(20), OUT empsalary DECIMAL(10, 2))
BEGINSELECT salary INTO empsalaryFROM employeesWHERE last_name = empname;
END //
DELIMITER ;# 调用
SET @empname := 'Abel';
CALL show_someone_salary2(@empname, @empsalary);SELECT @empsalary;

选中员工的领导,并将传入的形参赋值为领导的名称:

# 选中员工的领导,并将传入的形参赋值为领导的名称:
DELIMITER $
CREATE PROCEDURE show_mgr_name(INOUT empname VARCHAR(20))
BEGINSELECT last_name INTO empnameFROM employeesWHERE employee_id = (SELECT manager_idFROM employeesWHERE last_name = empname);END $
DELIMITER ;# 调用
SET @empname := 'Abel';
CALL show_mgr_name(@empname);SELECT @empname;

注意:在存储过程中进行的数据操作,一旦操作逻辑较为复杂时,难以进行排错

存储函数

存储函数就是指用户自定义的函数,这种函数必定有返回值。

创建一个存储函数用来返回Abel的邮箱

# 暂时改变分隔符
DELIMITER //
# 创建函数
CREATE FUNCTION email_by_name()
# 设置函数的返回值类型
RETURNS VARCHAR(25)
# 函数的一些限制,CONTAINS SQL意味着包含SQL语句,READS SQL DATA代表这是一条读数据,默认情况下这个限制是必须添加的DETERMINISTICCONTAINS SQLREADS SQL DATA
# 真正的函数体
BEGINRETURN (SELECT email FROM employees WHERE last_name = 'Abel');
END //
# 将分隔符修改回分号
DELIMITER ;# 调用函数
SELECT email_by_name();

创建一个存储函数,传入emp_id并查询其email并返回

注意如果不添加函数特征就必须设置全局属性log_bin_trust_function_creators属性为1

# 保证函数的创建必定成功,不需要添加函数的特征(DETERMINISTIC)
SET GLOBAL log_bin_trust_function_creators = 1;DELIMITER //
CREATE FUNCTION email_by_id(emp_id INT)
RETURNS VARCHAR(25)
BEGINRETURN (SELECT email FROM employees WHERE employee_id = emp_id);
END //
DELIMITER ;# 调用
SELECT email_by_id(100);# 使用变量进行调用
SET @temp1 := 100;
SELECT email_by_id(@temp1);

传入部门id并返回部门的人数

# 创建
DELIMITER //
CREATE FUNCTION count_by_id(dep_id INT)
RETURNS INT
BEGINRETURN (SELECT COUNT(*)FROM employeesWHERE department_id = dep_id);
END //
DELIMITER ;# 调用
SELECT count_by_id(100);

存储过程和存储函数的简单对比

存储过程更倾向于将查询所得到的结果赋值给某个参数,其更适用于更新修改的操作中,其可以有多个赋值操作

存储函数则会将结果作为返回值,其可以更加灵活的运用在各种SQL语句中,其返回值只能为一个,一般用于只有一个结果的查询操作

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

存储过程、函数的查看

注意以下信息都可以在控制台界面进行查看,在语句最后直接加’/G’进行查看

# 存储过程的查看创建信息
SHOW CREATE PROCEDURE avg_employee_salary;# 存储函数的查看创建信息
SHOW CREATE FUNCTION count_by_id;# 查看其状态信息
SHOW PROCEDURE STATUS;SHOW PROCEDURE STATUS LIKE 'avg_employee_salary';SHOW FUNCTION STATUS LIKE 'count_by_id';# 所有的存储过程与存储函数都会存储在information_schema.Routines中,对这个表进行查询也可以获取信息
SELECT *
FROM information_schema.Routines
WHERE ROUTINE_NAME = 'email_by_id'

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

注意存储过程与存储函数在创建好之后就不允许修改函数体,但我们可以对权限、注释等信息进行进一步修改

# 修改存储过程或存储函数的相关信息
ALTER PROCEDURE show_max_salary
SQL SECURITY INVOKER
COMMENT '最高工资'# 删除
DROP FUNCTION IF EXISTS count_by_id;

对于存储过程和存储函数的使用争议

其优点

  1. 可以提高SQL的执行效率:存储过程可以一次编译、多次使用,减少了SQL语句的编译次数,可以提高数据库调用的效率。
  2. 减少开发的工作量:将SQL语句封装为存储过程或函数,可以重复调用方法,不需要编写重复代码,可以减少开发的工作量。
  3. 安全性较强:在存储过程和存储函数中可以设置对用户的使用权限,以提高安全性。
  4. 可以减少网络传输量:具体代码被封装到存储过程或存储函数中,每次只需要进行调用,有效减少网络传输量。
  5. 良好的封装性:再进行较为复杂的数据库操作时,原本一条条的SQL可能会连接多次数据库,封装之后就只需要连接一次。

其缺点

  1. 可移植性差:存储过程或存储函数不可以跨数据库移植,在发生数据库变化的情况时需要重新编写。
  2. 调试困难(主要):只有少数的数据库支持存储过程的调试,在开发和维护的阶段都会有极大的不便。
  3. 版本管理困难:在一些其他情况发生时(例如数据库索引发生变化),会导致存储过程或存储函数失效,此时的版本问题就会十分麻烦
  4. 不适合高并发场景:在分库分表的场景下,存储过程就会十分难以维护。

http://www.ppmy.cn/news/1102029.html

相关文章

2024浙大MEM提面拿优秀笔试如何冲刺备考

浙大工程师学院对于参加浙大提前批面试并获得优秀资格的考生,提供了一个“笔试达到联考国家线即可拟录取”的优惠政策。这确实是吸引很多MEM考生参加提前批面试的原因之一。但是,即使获得了优秀资格,考生仍然需要在后续的联考笔试中达到一定的…

2023 IntelliJ IDEA下载、安装教程, 附详细图解

文章目录 下载与安装IDEA推荐阅读 下载与安装IDEA 首先先到官网下载最新版的IntelliJ IDEA, 下载后傻瓜式安装就好了 官网下载地址:https://www.jetbrains.com/ 1、下载完后在本地找到该文件,双击运行 idea 安装程序 2、点击 Next 3、选择安装路径&…

10.Xaml ListBox控件

1.运行界面 2.运行源码 a.Xaml 源码 <Grid Name="Grid1"><!--IsSelected="True" 表示选中--><ListBox x:Name="listBo

Vivado 2017.04版本安装教程

文章目录 前言一、vivado 简介二、vivado 下载三、vivado 安装四、vivado 申请证书五、关闭升级提醒六、资源自取 前言 本文记录了在 windows 11 下安装 vivado 2017 的详细步骤。 一、vivado 简介 Vivado 是 Xilinx 公司于 2012 推出的新一代集成设计环境&#xff0c;虽然目…

秒杀“超卖”问题

概述&#xff1a;限时秒杀活动在我们的日常生活中有很多&#xff0c;尤其在“双11”&#xff0c;“618”这类购物节活动中用户的并发数更是海量剧增&#xff0c;那么系统为了防止“超卖”秒杀商品&#xff0c;怎么做才能不影响性能的同时防止超卖。 为了解决“超卖”问题有两种…

日志平台搭建第二章:Linux使用docker安装elasticsearch-head

一、elasticsearch-head的安装启动 #下载镜像 docker pull alivv/elasticsearch-head #启动 docker run -d --name eshead -p 9100:9100 alivv/elasticsearch-head 查看日志 docker logs -f eshead 出现如下证明启动成功 浏览器访问9100端口&#xff0c;出现以下页面也说明…

mysql或ps提示 vcruntime140_1.dll丢失如何修复,5种方法办法你搞定

今天我在运行一款新安装的软件时&#xff0c;突然遇到了一个让我十分困扰的问题——系统提示vcruntime140_1.dll文件丢失。这个问题导致我无法正常使用这个软件&#xff0c;我也不知道怎么回事&#xff0c;所以我在网上找了一天终于让我找到解决这个问题的方法了&#xff0c;今…

Python|合并两个字典的几种方法

在Python中&#xff0c;有多种方法可以通过使用各种函数和构造函数来合并字典。在本文中&#xff0c;我们将讨论一些合并字典的方法。 1. 使用方法update() 通过使用Python中的update()方法&#xff0c;可以将一个列表合并到另一个列表中。但是在这种情况下&#xff0c;第二个…