MySQL 存储过程详解:概念、创建与删除全教程

📑 目录

  • [1 什么是MySQL存储过程](#1 什么是MySQL存储过程)
    • [1.1 存储过程核心定义](#1.1 存储过程核心定义)
    • [1.2 存储过程优缺点](#1.2 存储过程优缺点)
    • [1.3 适用业务场景](#1.3 适用业务场景)
  • [2 存储过程的创建语法实操](#2 存储过程的创建语法实操)
    • [2.1 无参存储过程创建](#2.1 无参存储过程创建)
    • [2.2 带入参存储过程创建](#2.2 带入参存储过程创建)
    • [2.3 存储过程调用方式](#2.3 存储过程调用方式)

1. 什么是MySQL存储过程]

** 存储过程:一组完成特定功能的语句集,经过编译后储存在数据库中,用户可以指定存储过程的名字和参数来进行执行,执行完毕得到相应结果;**

 用大白话来说就是:存储过程就是提前把一堆 SQL 语句打包写好,存在 MySQL 数据库里,给这段打包代码起个名字 。后续不用重复写一堆 SQL,直接调用名字就能一次性执行全部语句

 我们可以类比与Java中的方法,或者C语言中的函数

 正如,SQL语句我们可以理解为:方法体里面的语句

 当我们调用这个方法的时候,就会完成指定的任务之后,就会得到对应的结果;

特点:

  1. 存在数据库端:代码保存在 MySQL 服务器,不是 Java、本地文件里;
  2. 一次编译,多次运行:第一次调用编译,后续直接执行,大批量 SQL 效率更高;
  3. 支持入参、出参,可以外部传值控制 SQL 逻辑;
  4. 可以写流程控制:if 判断、while 循环,让 SQL 拥有简单编程能力。
1.1 存储过程核心定义

 正常情况下,我们的数据库主要负责数据的存储和检索工作

 Java 服务负责流程控制 (if 判断、循环、事务、业务计算)

 而使用存储过程模式:

 数据库包揽流程控制、判断、循环、运算、事务;Java 只充当 "调用方",只负责传参、拿返回结果,不再参与业务判断。

例如:

  • 普通写法:Java 查余额、if 判断钱够不够、try 控制事务、加减金额;
  • 存储过程:Java 只传转账双方 ID 和金额,剩下查余额、判断、扣钱加钱、出错回滚全由 MySQL 跑完。


[🔙 返回目录](#🔙 返回目录)


1.2 存储过程优缺点

优点:

  1. 性能优化
     存储过程,是在创建时编译放在数据库中的,执行存储过程时,执行速度会比执行单个SQL语句集快;
  2. 代码重用
     创建的存储过程,可以重复被使用,避免重复代码;
  3. 安全性
     存储过程可以限制直接访问数据库,通过间接访问;
  4. 降低耦合性
     当创建的表结构发生变化时,我们只需要修改对应的存储过程即可
  5. 事物管理
     可以在存储过程中实现比较复杂的事物逻辑

缺点:

  1. 可移植性差
     存储过程不能夸数据库进行使用,更换数据库时,需要重新编写;
  2. 调试困难
     只有少数情况下数据库管理系统支持存储过程调试,我们在使用命令行窗口时,调试非常困难,找bug很艰难;
  3. 不适合高并发的场景
     在高并发场景下,如果使用存储过程来管理数据库,可能会增加数据库压力,本来我们数据库就是代码执行过程中最慢的时候,此时数据库就很难以维护;

[🔙 返回目录](#🔙 返回目录)


1.3 适用业务场景

适合场景: 类似于一下场景

  批量数据处理:批量修改、批量统计、定时归档;

  复杂多SQL组合:多表查询、多步骤计算、报表统计;

  闭环事务操作:下单、支付、库存扣减等强一致性业务;

 逻辑分支繁多:大量if/判断依赖数据库字段做分支。

不推荐场景

 .需要频繁迭代改动的业务;

  需要跨库操作、依赖Java中间件逻辑;

  追求数据库横向分库分表的大型分布式系统。

 主要使用场景日常开发中按照业务需求即可;
[🔙 返回目录](#🔙 返回目录)


2. 存储过程的创建语法实操

语法:

sql 复制代码
-- 修改sql语句结束标识符为 //
delimiter //
-- 创建存储过程
create procedure 存储过程名 (参数列表)
begin
-- sql 语句
end //
-- 修改sql语句结束标识符为 ;
delimiter ;

 为什么我们此时需要修改结束标识符?

 我们知道我们在命令行客户端进行增删改查的时候,我们是使用;来表示这条语句结束

 如果我们此时不加;此时,编译器就不知道你到底结束没;

例如:

 此时就会出现这种情况;
[🔙 返回目录](#🔙 返回目录)


2.1 无参存储过程创建

 我们先创建一个学生表;

sql 复制代码
create table student(
    id int primary key auto\_increment,
    name varchar(40) default '匿名',
    age int not null
);

 默认数据就是好久之前写博客创建的数据:

 此时表中数据是这样的4条数据,只有名字,id,和年龄;

 举个简单的例子:我们需要查询年龄大于40岁的人,使用存储过程来创建

sql 复制代码
delimiter //
create procedure p_test()
begin 
select id,name,age from student where age > 40;
end //
delimiter ;

 此时我们存储过程就已经创建好了:


[🔙 返回目录](#🔙 返回目录)


2.2 带入参存储过程创建

还是以刚才的数据为例子:

创建存储过程:我们需要手动指定,年龄大于***岁的存储过程

sql 复制代码
delimiter //
create procedure query_student_by_age(in int)
begin
    select id,name,age from student where age > param_age;
end //
delimiter ;

in:参数方向关键字

param_age:自定义参数名

int:参数的数据类型

写法 含义 调用特点
in param_age int 外部给存储过程传数字 调用直接写固定数字:call xxx(42)
out total int 存储过程向外吐出数字 调用必须用@变量承接:call xxx(42,@res)
inout num int 既能传入,又能改完带回 调用必须用@变量

例如:

sql 复制代码
delimiter //
create procedure p_test(in val int)
begin 
select id.name,age from student where  val >40;
end //
delimiter ;

 此时我们带参数的存储过程就已经创建好了;

 我们也可以使用inout num int的方式来创建

sql 复制代码
set @num :=10;

delimiter //
create procedure p_test(in val int)
begin
set @num = @num+val;
end //
delimiter ;

select @num;


[🔙 返回目录](#🔙 返回目录)


2.3 存储过程调用方式

语法:

sql 复制代码
call 存储过程名字(参数);

作用:存储过程向外输出结果,必须用@自定义变量承接,不能传常量。

例如调用我们上诉创建的查看:

sql 复制代码
delimiter //
create procedure p_test(in val int)
begin
    select id,name,age from student where age > val;
end //
delimiter ;
call p_test(40);

 结果:


[🔙 返回目录](#🔙 返回目录)


相关推荐
ttwuai1 小时前
AI 生成后台删除按钮后,MySQL 软删除和唯一索引怎么验
数据库·mysql·golang
想你依然心痛1 小时前
用MySQL玩转数据可视化:从SQL查询到动态图表的完整实战
sql·mysql·信息可视化
2zcode1 小时前
项目文档:基于MATLAB最小二乘支持向量机的睡眠分期智能监测系统设计与实现
开发语言·支持向量机·matlab
twcc_come1 小时前
安全策略配置实验报告
开发语言·php
张人玉2 小时前
基于 Vue 3 + ECharts + Express + SQLite 构建的新能源汽车销量数据分析与可视化平台——新能源汽车销量数据分析系统
数据库·vue.js·sqlite·echarts
2601_963870222 小时前
基于Python的晋江文学城热门作品数据分析与可视化
开发语言·python·数据分析
其实防守也摸鱼3 小时前
Kimi K3深度测评:长文本之外的真实力
运维·开发语言·网络·人工智能·python·学习·安全
冻柠檬飞冰走茶3 小时前
PTA基础编程题目集 7-7 12-24小时制(C语言实现)
c语言·开发语言·数据结构·算法
梦幻通灵3 小时前
Java中finally失效的几种情况【持续更新】
java·开发语言