尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

完整教程:MySQL 存储过程完整实战手册---一篇吃透 Stored Procedure

完整教程:MySQL 存储过程完整实战手册---一篇吃透 Stored Procedure
📅 发布时间:2026/6/20 12:30:49

完整教程:MySQL 存储过程完整实战手册---一篇吃透 Stored Procedure

2025-09-21 15:15  tlnshuju  阅读(0)  评论(0)    收藏  举报

目录

  1. 存储过程是什么(作用总览)
  2. 典型使用场景与真实案例
  3. 使用前必须知道的 7 大注意事项
  4. 语法骨架与变量详解
  5. 参数模式:IN / OUT / INOUT
  6. 流程控制:IF / CASE / 循环
  7. 游标(Cursor):行级遍历
  8. 条件处理程序(Handler):捕获异常
  9. 存储函数(Function)与过程的区别
  10. 性能 & 运维 FAQ
  11. 一句话总结

1. 存储过程是什么(作用总览)

  • 预编译的数据库代码块,存储在服务器端
  • 可接受参数、返回结果、封装复杂业务
  • 一次创建,多次调用 → 减少网络往返、提高性能
  • 支持事务、异常处理、游标,实现“数据库内脚本”

一句话:把多条 SQL + 控制逻辑打包成“数据库里的方法”。


2. 典型使用场景与真实案例

场景说明示例片段
① 批量数据清洗ETL nightly job遍历临时表,异常行写入错误日志
② 订单下单闭环扣库存 → 写订单 → 记日志三表操作包事务
③ 对账/结转月末快照游标逐行累计金额
④ 分页返回 + 总计Web 报表一次返回“列表+总数”OUT 参数带回总数
⑤ 安全隔离只开放 CALL 权限,不暴露表隐藏底层字段

3. 使用前必须知道的 7 大注意事项

  1. 移植性差:MySQL / SQL Server / Oracle 语法差异大
  2. 调试困难:8.0 前无断点,靠 SELECT debug_info;
  3. 版本管理:过程代码存库,要入 Git + 迁移脚本
  4. 过度复杂会使业务逻辑碎片化 → 轻量封装即可
  5. 默认权限 DEFINER 需回收 SUPER,防止 SQL 注入提权
  6. 大循环注意 max_sp_recursion_depth & innodb_lock_wait_timeout
  7. 线上大表用游标时,务必加 WHERE 范围 + 主键索引,防止全表锁

4. 语法骨架与变量详解

DELIMITER $$
CREATE PROCEDURE sp_demo(IN p_age INT,
OUT p_cnt INT)
BEGIN
/* 1. 局部变量 */
DECLARE v_total INT DEFAULT 0;
DECLARE v_msg VARCHAR(100);
/* 2. 业务逻辑 */
SELECT COUNT(*) INTO v_total
FROM user
WHERE age > p_age;
SET p_cnt = v_total;
-- 返回给调用者
END$$
DELIMITER ;

变量类型对比

类型作用域赋值方式初始值
局部变量 DECLARE当前 BEGIN…ENDSET / SELECT ... INTODEFAULT 或 NULL
用户变量 @var当前会话SET @var=1;无,需手动初始化
参数 IN/OUT/INOUT过程内部调用者传入调用者给定

5. 参数模式:IN / OUT / INOUT

CREATE PROCEDURE sp_param_demo(
IN p_id INT, -- 只读
OUT p_name VARCHAR(50), -- 返回
INOUT p_sal DECIMAL(10,2) -- 双向
)
BEGIN
SELECT name, salary INTO p_name, p_sal
FROM employee
WHERE emp_id = p_id;
SET p_sal = p_sal * 1.1;
-- 加薪 10%
END;
-- 调用
SET @sal = 0;
CALL sp_param_demo(100, @name, @sal);
SELECT @name, @sal;
-- 拿到结果

6. 流程控制:IF / CASE / 循环

① IF

IF v_total >
100 THEN
SET v_msg = 'many';
ELSEIF v_total >
10 THEN
SET v_msg = 'some';
ELSE
SET v_msg = 'few';
END IF;

② CASE

CASE v_level
WHEN 1 THEN SET v_desc = 'A';
WHEN 2 THEN SET v_desc = 'B';
ELSE SET v_desc = 'C';
END CASE;

③ 循环:LOOP / WHILE / REPEAT

-- WHILE 示例:批量插入 100 条
CREATE PROCEDURE sp_batch_insert()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 100 DO
INSERT INTO log(msg) VALUES (CONCAT('msg-',i));
SET i = i + 1;
END WHILE;
END;

7. 游标(Cursor):行级遍历

场景:对结果集逐行处理。

CREATE PROCEDURE sp_cursor_sum(OUT o_total DECIMAL(10,2))
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE v_sal DECIMAL(10,2);
DECLARE cur CURSOR FOR SELECT salary FROM employee;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- ④ 异常处理
SET o_total = 0;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_sal;
IF done THEN
LEAVE read_loop;
END IF;
SET o_total = o_total + v_sal;
END LOOP;
CLOSE cur;
END;

8. 条件处理程序(Handler):捕获异常

语法

DECLARE <handler_type>HANDLER FOR <condition_value><statement>;
  • handler_type: CONTINUE / EXIT / UNDO(仅 DB2)
  • condition_value: SQLSTATE '02000' / NOT FOUND / SQLEXCEPTION

示例:重复键不中断,继续跑

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000'
BEGIN
INSERT INTO err_log(info) VALUES ('duplicate key');
END;

9. 存储函数(Function)与过程的区别

对比项存储过程存储函数
返回值0~n 个 OUT/INOUT 参数必须返回一个标量
调用方式CALL proc()SELECT func() 可嵌在 SQL 内部
事务/游标✅ 支持✅ 支持(8.0+)
副作用可更新表若声明 DETERMINISTIC 仍可更新表

函数示例:计算个人所得税

CREATE FUNCTION f_tax(p_sal DECIMAL(10,2))
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
DECLARE v_tax DECIMAL(10,2);
IF p_sal <= 5000 THEN
SET v_tax = 0;
ELSE
SET v_tax = (p_sal - 5000) * 0.2;
END IF;
RETURN v_tax;
END;
-- 使用
SELECT name, salary, f_tax(salary) AS tax FROM employee;

10. 性能 & 运维 FAQ

Q1 存储过程真的比应用程序快?

  • 减少网络往返,批量逻辑快 2~3 倍;但 CPU 密集运算不如应用层。
    Q2 如何调试?
  • MySQL 8.0 可用 SET @debug = 1; 内部 SELECT debug_info;
  • 或拆成临时表,每一步 INSERT INTO tmp_log VALUES (step, value);
    Q3 线上热更新?
  • CREATE OR REPLACE 会加元数据锁,大并发时先建新版本,再 RENAME 切换。

一句话总结

存储过程 = “数据库内的脚本方法”,擅长封装、批量、事务、行级遍历;
牢记“复杂逻辑适度下沉、版本+权限+索引三件套”,就能在性能与安全之间取得最佳平衡。

相关新闻

  • 「MCOI-05」魔仙
  • BlueHat v18 会议资料现已发布:前沿安全技术与漏洞缓解策略
  • label和brand的区别(品牌=brand?错了,你们的英语都学错了!)

最新新闻

  • ApexSQL Log 2018:SQL Server事务日志可视化分析与精准回滚工具
  • 孤能子视角:涌现的本体论、动力学与认识论
  • Redis的数据结构
  • 文成未来教育:专注高考志愿填报的专业升学规划机构 - 起跑123
  • 东莞市新开业或装修后理发店卫生+空气检测,公共场所检测 - 公共场所卫生检测
  • 2026年6月宝玑官方售后服务网络全新升级:中国区60+门店地址、电话信息同步启用 - 亨得利中国服务中心

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号