news 2026/7/13 14:20:26

实验七 存储过程:从零到一,掌握数据库业务逻辑封装

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
实验七 存储过程:从零到一,掌握数据库业务逻辑封装

1. 存储过程是什么?为什么需要它?

第一次接触数据库开发时,我总在Java代码里写满SQL语句。每次统计用户订单都要重复写相同的联表查询,直到同事提醒:"你这代码像复读机啊!"后来才知道,数据库里有种叫存储过程的黑科技,能把复杂SQL操作打包成可重复调用的功能模块。

简单来说,存储过程就像是预装在数据库里的APP。比如电商系统要计算会员积分,原本需要在Java/Python里写十几行代码与数据库交互,现在只需调用一句CALL calc_points(用户ID)。我做过测试:一个包含5表关联的统计查询,用存储过程比应用程序处理快3倍,因为减少了网络传输和SQL解析开销。

2. 创建你的第一个存储过程

2.1 基础创建语法

先看个供应商管理的例子。假设有供应商表S和供货记录表SPJ,现在要给S表增加供应总量统计列:

ALTER TABLE s ADD sqty INT DEFAULT 0;

接下来创建存储过程自动更新这个统计值:

DELIMITER // CREATE PROCEDURE update_supply_total() BEGIN UPDATE s SET sqty = (SELECT SUM(qty) FROM spj WHERE spj.sno = s.sno); END // DELIMITER ;

这里有个坑要注意:MySQL默认用分号结束语句,但存储过程体内也有分号。所以先用DELIMITER //临时修改结束符,就像告诉数据库:"看到//再执行这段代码"。

2.2 执行存储过程

调用存储过程比点外卖还简单:

CALL update_supply_total();

执行后查看S表,所有供应商的sqty列都会自动更新。我在项目中用这招处理月度报表生成,原本需要15分钟的统计任务现在3分钟搞定。

3. 带参数的存储过程实战

3.1 输入参数(IN)的使用

查询特定供应商的供货总量时,可以用IN参数动态传入供应商编号:

CREATE PROCEDURE get_supply_qty(IN supplier_id CHAR(2)) BEGIN SELECT SUM(qty) FROM spj WHERE sno = supplier_id; END

调用时指定参数值:

CALL get_supply_qty('S1');

3.2 输出参数(OUT)的妙用

需要获取计算结果给其他SQL使用时,OUT参数就派上用场了:

CREATE PROCEDURE get_supply_qty_out( IN supplier_id CHAR(2), OUT total_qty INT ) BEGIN SELECT SUM(qty) INTO total_qty FROM spj WHERE sno = supplier_id; END

调用方式很特别:

CALL get_supply_qty_out('S1', @result); SELECT @result; -- 这里显示输出值

3.3 输入输出参数(INOUT)

最灵活的是INOUT参数,既能输入又能输出。比如实现计数器:

CREATE PROCEDURE counter(INOUT num INT, IN increment INT) BEGIN SET num = num + increment; END

使用时需要先设置变量:

SET @count = 1; CALL counter(@count, 5); -- 结果@count变为6

4. 存储过程进阶技巧

4.1 条件判断与错误处理

在新增供应商时加入存在性检查:

CREATE PROCEDURE add_supplier( IN p_sno CHAR(2), IN p_name VARCHAR(10), IN p_status INT, IN p_city VARCHAR(10) ) BEGIN DECLARE exist_count INT; SELECT COUNT(*) INTO exist_count FROM s WHERE sno = p_sno; IF exist_count > 0 THEN SELECT '供应商已存在!' AS message; ELSE INSERT INTO s VALUES(p_sno, p_name, p_status, p_city); END IF; END

4.2 使用游标处理多行数据

当需要逐行处理数据时,游标是唯一选择。比如批量修改项目信息:

CREATE PROCEDURE update_projects() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE j_id CHAR(2); DECLARE cur CURSOR FOR SELECT jno FROM j; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO j_id; IF done THEN LEAVE read_loop; END IF; UPDATE j SET city = '北京' WHERE jno = j_id; END LOOP; CLOSE cur; END

5. 存储过程的管理与优化

5.1 查看和修改存储过程

查看所有存储过程:

SHOW PROCEDURE STATUS;

查看具体定义:

SHOW CREATE PROCEDURE update_supply_total;

修改存储过程需要先删除再重建,没有ALTER PROCEDURE语法:

DROP PROCEDURE IF EXISTS update_supply_total; CREATE PROCEDURE update_supply_total() ...

5.2 性能优化建议

  1. 使用COMMENT添加说明:三个月后你肯定记不清这个存储过程是干嘛的

    CREATE PROCEDURE calc_stats() COMMENT '用于月度统计报表' BEGIN -- 过程体 END
  2. 避免过度使用游标:我曾在处理10万条数据时,用游标花了2小时,改成批量UPDATE后只要3分钟

  3. 定期维护:存储过程会缓存执行计划,当表结构变化后记得重新编译

    CALL update_supply_total(); -- 首次执行会编译
  4. 权限控制:只给必要用户EXECUTE权限

    GRANT EXECUTE ON PROCEDURE db.update_supply_total TO 'report_user';

6. 真实项目经验分享

去年做物流系统时,我设计了一个智能调度存储过程。它接收区域ID和时间范围参数,自动完成以下操作:

  1. 检查该区域可用车辆
  2. 计算每个司机的累计工时
  3. 根据货物类型匹配合适车型
  4. 生成最优分配方案

原本需要200行Java代码的逻辑,现在只需30行SQL存储过程。最惊喜的是执行时间从45秒降到5秒,因为所有计算都在数据库内部完成,避免了数千次网络往返。

有个坑要提醒:存储过程调试比较麻烦。我的经验是:

  1. 先用SELECT输出中间结果
  2. 复杂逻辑拆分成小过程
  3. 在测试环境充分验证

存储过程就像数据库里的瑞士军刀,用好了能大幅提升效率。但也要避免滥用,对于简单的CRUD操作,直接写SQL可能更清晰。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/13 14:19:20

Policy Plus:Windows全版本组策略编辑器终极解决方案

Policy Plus:Windows全版本组策略编辑器终极解决方案 【免费下载链接】PolicyPlus Local Group Policy Editor plus more, for all Windows editions 项目地址: https://gitcode.com/gh_mirrors/po/PolicyPlus 还在为Windows家庭版无法使用组策略编辑器而烦恼…

作者头像 李华
网站建设 2026/7/13 14:19:07

全景相机模型:从统一投影到多视角图像生成

1. 全景相机模型基础:从鱼眼到360度视野第一次接触全景相机时,我被它夸张的球形画面震撼到了——这完全颠覆了传统相机的成像逻辑。普通相机就像从一个小孔看世界(针孔模型),而全景相机则像把整个场景"揉"成…

作者头像 李华
网站建设 2026/7/13 14:19:01

混合精度训练实战:从原理到PyTorch与PaddlePaddle实现

1. 混合精度训练的核心原理混合精度训练的本质是在神经网络训练过程中,智能分配计算精度。想象一下,你在记账时,大额支出用精确到元(FP32),小额零钱用精确到角(FP16),既保…

作者头像 李华
网站建设 2026/7/13 14:18:41

Verilog语法:for循环的使用心得

在硬件设计中,往往会遇到大量相同电路的设计需求。在这种情况下,如果能够总结出这些电路的一般规律,使用for语句不仅可以减少代码量(如果代码量是工作量的话,不推荐使用for语句),并且在一定程度…

作者头像 李华
网站建设 2026/7/13 14:18:07

WSL2 Ubuntu 安装Hermes Agent

一、相关链接 官网 https://hermes-agent.nousresearch.com/ 国内镜像站 https://hermes-agent.ac.cn/ 文档 https://hermes-agent.nousresearch.com/docs/ 中文文档 https://hermes-agent.ac.cn/docs github https://github.com/NousResearch/hermes-agent 二、安装Ubuntu…

作者头像 李华