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

mysql之存储过程

存储过程是一组预先编译并存储在数据库中的 SQL 语句集合,可通过调用名称执行,支持参数传入 / 传出、逻辑判断、循环等复杂操作。它是 MySQL 实现业务逻辑封装的核心工具,常用于批量数据处理、复杂计算、权限管控等场景。


存储过程的创建与调用

-- 修改语句结束符(避免与存储过程内的 ; 冲突)
DELIMITER $$CREATE PROCEDURE 存储过程名([IN/OUT/INOUT 参数名 数据类型, ...])
BEGIN-- 存储过程的 SQL 逻辑(可包含条件、循环、事务等)
END$$-- 恢复语句结束符
DELIMITER ;
参数类型 作用 示例
IN 输入参数:调用时传入值,存储过程内可读不可改 IN user_id INT
OUT 输出参数:存储过程内赋值,调用后可获取结果 OUT total_amount DECIMAL(10,2)
INOUT 输入输出参数:调用时传入值,过程内可修改并返回 INOUT count INT

实战示例

场景 1:基础存储过程(无参数)

需求:查询所有未删除的用户信息。

DELIMITER $$
CREATE PROCEDURE `sp_query_all_user`()
BEGIN-- SQL 逻辑:查询 is_deleted=0 的用户SELECT id, name, age, city FROM `user` WHERE is_deleted = 0;
END$$
DELIMITER ;-- 调用存储过程
CALL `sp_query_all_user`();

场景 2:带 IN 参数的存储过程

需求:根据用户 ID 查询其订单总数。

DELIMITER $$
CREATE PROCEDURE `sp_get_user_order_count`(IN p_user_id INT)
BEGINSELECT COUNT(*) AS order_count FROM `order_info` WHERE user_id = p_user_id;
END$$
DELIMITER ;-- 调用存储过程(传入用户 ID=1)
CALL `sp_get_user_order_count`(1);

场景 3:带 IN+OUT 参数的存储过程

需求:根据用户 ID 计算其订单总金额(通过 OUT 参数返回结果)。

DELIMITER $$
CREATE PROCEDURE `sp_calc_user_total_amount`(IN p_user_id INT,OUT p_total_amount DECIMAL(10,2)
)
BEGINSELECT SUM(amount) INTO p_total_amount FROM `order_info` WHERE user_id = p_user_id;
END$$
DELIMITER ;-- 调用存储过程(定义变量接收输出参数)
SET @total = 0;
CALL `sp_calc_user_total_amount`(1, @total);
SELECT @total AS user_total_amount;  -- 查看结果

存储过程的管理(查询、修改、删除)

查询存储过程

(1)查看数据库中所有存储过程

-- 方法1:SHOW 命令
SHOW PROCEDURE STATUS WHERE DB = '你的数据库名';-- 方法2:查询系统表(更灵活)
SELECT ROUTINE_NAME, ROUTINE_TYPE 
FROM information_schema.ROUTINES 
WHERE ROUTINE_SCHEMA = '你的数据库名' AND ROUTINE_TYPE = 'PROCEDURE';

(2)查看存储过程的创建语句(核心)

SHOW CREATE PROCEDURE `sp_get_user_order_count` \G;

删除存储过程

DROP PROCEDURE [IF EXISTS] 存储过程名;-- 示例:删除存储过程
DROP PROCEDURE IF EXISTS `sp_query_all_user`;

存储过程的变量与逻辑控制

变量声明与赋值

(1)局部变量(存储过程内有效)

-- 声明变量:DECLARE 变量名 数据类型 [DEFAULT 默认值]
DECLARE var_name INT DEFAULT 0;-- 赋值方式1:SELECT ... INTO ...
SELECT COUNT(*) INTO var_name FROM `user`;-- 赋值方式2:SET 语句
SET var_name = 10;

(2)用户变量(会话内有效)

用户变量以 @ 开头,无需声明,直接赋值,可跨存储过程使用。

SET @user_id = 1;
CALL `sp_get_user_order_count`(@user_id);

条件判断(IF/CASE

(1)IF 语句

IF age >= 18 THENSET group_name = '成年人';
ELSEIF age >= 12 THENSET group_name = '青少年';
ELSESET group_name = '儿童';
END IF;

(2)case语句

CASE WHEN age >= 18 THEN SELECT '成年人';WHEN age >= 12 THEN SELECT '青少年';ELSE SELECT '儿童';
END CASE;

循环控制(WHILE/REPEAT/LOOP

(1)WHILE 循环(先判断后执行)

DECLARE i INT DEFAULT 1;
WHILE i <= 10 DO-- 循环体逻辑:插入 10 条测试数据INSERT INTO `test` (num) VALUES (i);SET i = i + 1;
END WHILE;

(2)REPEAT 循环(先执行后判断)

DECLARE i INT DEFAULT 1;
REPEATINSERT INTO `test` (num) VALUES (i);SET i = i + 1;
UNTIL i > 10 END REPEAT;

高并发场景不建议使用存储过程

存储过程的逻辑在数据库端执行,复杂逻辑会占用大量数据库 CPU 和内存资源,导致数据库成为系统瓶颈,降低高并发场景的吞吐量。

http://www.jsqmd.com/news/624698/

相关文章:

  • 深圳市宇亿再生资源回收有限公司-坪山区线路板边料回收哪家专业 - LYL仔仔
  • Pixel Experience刷机全攻略:从解锁到Magisk安装
  • PyTorch 2.8镜像实际效果:Transformer+Accelerate在多卡4090D集群表现
  • 【技术解析】思维链提示赋能大语言模型:软件漏洞智能检测与修复的实践突破
  • 基于 Vite + Electron + React 的跨平台桌面应用开发环境全攻略
  • 电子半导体行业:高纯度铁氟龙管的应用详解 - 众鑫氟塑铁氟龙管
  • 归并排序力扣题(leetcode)鲁
  • Graphormer部署进阶:Prometheus+Grafana监控GPU利用率与QPS指标
  • 《计算机网络》深入学:比较 RIP 和 OSPF 协议
  • MOSFET体二极管电流极限揭秘:从防反接电路到BUCK应用
  • 从AT24C02 EEPROM读写实战,反推Verilog I2C控制器的设计思路与调试技巧
  • 豆包AI时代企业获客新解:高性价比GEO优化机构如何助力品牌自然增长 - 品牌2026
  • Ostrakon-VL-8B应用案例:基于YOLOv11的餐盘多目标检测与成分识别
  • 5分钟掌握B站视频下载神器:BilibiliDown终极免费指南
  • ESP32+MicroPython实战:5分钟搞定LED闪烁(附完整代码)
  • 深度学习笔记---空洞卷积如何扩大感受野而不丢失分辨率
  • EPLAN 箱柜清单部件缺失排查指南
  • 网盘直链下载助手终极指南:八大平台文件下载神器全面解析
  • 京城信德斋与“信德斋”无关联 藏家需谨慎甄别 - 品牌排行榜单
  • AT32F403A高级定时器:死区插入与重复计数器实战解析
  • Ubuntu20.04下JAX+CUDA12.1环境搭建避坑指南:解决cuSPARSE库缺失问题
  • 降权与重塑:环保包装如何从“及格线”走向“天花板”
  • 2026盒马鲜生礼品卡回收品牌推荐榜 - 京顺回收
  • 【OpenClaw】通过 Nanobot 源码学习架构---()总体磁
  • 亲测武汉五恒系统供应商实践分享
  • /proc/interrupts
  • OpenBMC开发实战指南——i2c工具链深度解析与应用场景
  • 掌握Multi-Agent协作:让你的AI项目更高效,收藏这份进阶指南!
  • GME多模态向量模型快速部署:开箱即用的图文向量服务
  • PID调参实战:如何让你的STM32四轴无人机飞得稳?从原理到代码的避坑指南