存储过程详解:把SQL逻辑“打包”存起来,下次一键调用!|转行学DB第12天

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 数据库也能“写脚本”!存储过程是预编译的SQL代码包,支持参数、变量、条件判断与循环,可一键执行多步操作(如更新+插入+删除),提升复用性、减少网络开销。新手入门必备进阶技能!

不用每次都重复写复杂操作,数据库也能“写脚本”

大家好呀!我是数据库小学妹👋

前几篇我们学会了视图,可以把复杂的查询存成虚拟表。但如果我们遇到这种情况如何解决:

如果我想执行一连串的操作(比如先更新A表,再插入B表,再删除C表),每次都要写好几条SQL。有没有办法把这一整套动作“打包”存起来,下次直接调用?

当然有!今天我就把自己学会的存储过程分享出来——它就像给数据库写“脚本”,把一堆SQL语句封装成一个整体,以后一句命令就能执行全部。


一、什么是存储过程?数据库里的“脚本文件”

存储过程是一段预先编译好并存储在数据库中的SQL代码。你可以给它起个名字,然后像调用函数一样执行它。

💡 类比:你在设计软件里录了一个“动作”宏,一键完成多步操作。存储过程就是数据库的“宏”。

为什么需要它?

  • 复用性:写一次,调用无数次
  • 减少网络传输:只需要发一条 CALL 命令,而不是几十行SQL
  • 逻辑封装:把复杂的业务逻辑藏在存储过程里,应用层调用更简单

二、什么是存储过程?

📚基本语法

DELIMITER //

CREATE PROCEDURE 过程名()
BEGIN
    -- 这里写SQL语句
    SELECT 'Hello, Database!';
END //

DELIMITER ;
  • DELIMITER // 是改变MySQL的语句结束符(因为过程体里可能有分号),执行完再改回 ;
  • BEGIN...END 之间放你要执行的SQL

调用存储过程

CALL 过程名();

🎯实战:无参存储过程示例

创建一个向日志表插入当前时间的存储过程:

DELIMITER //

CREATE PROCEDURE InsertLog()
BEGIN
    INSERT INTO logs (message, created_at) 
    VALUES ('存储过程被执行了', NOW());
END //

DELIMITER ;

调用:

CALL InsertLog();

每次调用,logs 表里就会多一行记录。


三、存储过程的参数类型

参数可以让存储过程处理不同的数据。参数有三种类型:
image_04201.png

示例1:IN参数——根据用户ID查询姓名

DELIMITER //

CREATE PROCEDURE GetUserName(IN user_id INT)
BEGIN
    SELECT name FROM users WHERE id = user_id;
END //

DELIMITER ;

调用:

CALL GetUserName(1);

示例2:OUT参数——统计用户数量并返回

DELIMITER //

CREATE PROCEDURE GetUserCount(OUT total INT)
BEGIN
    SELECT COUNT(*) INTO total FROM users;
END //

DELIMITER ;

调用:

CALL GetUserCount(@count);
SELECT @count;   -- 查看输出参数的值

示例3:INOUT参数——对传入值做运算

DELIMITER //

CREATE PROCEDURE DoubleNumber(INOUT num INT)
BEGIN
    SET num = num * 2;
END //

DELIMITER ;

调用:

SET @a = 5;
CALL DoubleNumber(@a);
SELECT @a;   -- 结果是 10

四、存储过程的控制结构

在存储过程内部可以定义变量、使用条件判断和循环语句。

🎯定义变量

DECLARE 变量名 数据类型 [DEFAULT 默认值];

🎯IF-ELSE判断示例:根据分数返回等级

DELIMITER //

CREATE PROCEDURE GetGrade(IN score INT, OUT grade VARCHAR(10))
BEGIN
    IF score >= 90 THEN
        SET grade = '优秀';
    ELSEIF score >= 60 THEN
        SET grade = '及格';
    ELSE
        SET grade = '不及格';
    END IF;
END //

DELIMITER ;

调用:

CALL GetGrade(85, @g);
SELECT @g;   -- 及格

🎯CASE语句:多个条件时更清晰

比IF更适合多个固定值的匹配:

DELIMITER //

CREATE PROCEDURE GetWeekName(IN day_num INT, OUT week_name VARCHAR(10))
BEGIN
    CASE day_num
        WHEN 1 THEN SET week_name = '星期一';
        WHEN 2 THEN SET week_name = '星期二';
        WHEN 3 THEN SET week_name = '星期三';
        WHEN 4 THEN SET week_name = '星期四';
        WHEN 5 THEN SET week_name = '星期五';
        WHEN 6 THEN SET week_name = '星期六';
        WHEN 7 THEN SET week_name = '星期日';
        ELSE SET week_name = '无效数字';
    END CASE;
END //

DELIMITER ;

🎯WHILE循环:先判断后执行

批量插入数据(1到n):

DELIMITER //

CREATE PROCEDURE BatchInsert(IN n INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    WHILE i <= n DO
        INSERT INTO test_table (value) VALUES (i);
        SET i = i + 1;
    END WHILE;
END //

DELIMITER ;

🎯LOOP循环:需配合 LEAVE 退出

DELIMITER //

CREATE PROCEDURE LoopExample(IN n INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    loop_label: LOOP
        IF i > n THEN
            LEAVE loop_label;   -- 退出循环
        END IF;
        INSERT INTO test_table (value) VALUES (i);
        SET i = i + 1;
    END LOOP;
END //

DELIMITER ;

💡 什么时候用哪种?

  • 简单条件分支 → IF
  • 多个固定值匹配 → CASE
  • 已知循环次数 → WHILE
  • 需要灵活控制(如无限循环+条件跳出) → LOOP

注意​:循环在数据量大时性能很差,实战中尽量避免。这里仅做语法演示。


五、查看和删除存储过程

查看所有存储过程

SHOW PROCEDURE STATUS WHERE Db = '你的数据库名';

查看存储过程的创建语句

SHOW CREATE PROCEDURE 过程名;

删除存储过程

DROP PROCEDURE IF EXISTS 过程名;

六、新手避坑指南(血泪总结)

image_04202.png


七、存储过程与视图的区别?

image_04203.png

简单总结:

  • 只是查数据→ 视图
  • 需要返回单个计算结果→ 函数
  • 需要执行一系列操作(包括更新)→ 存储过程

八、今日学习心得

今天的内容总结成三句话:

  1. 存储过程就是数据库里的“函数”,封装复杂逻辑,一次编写多次调用
  2. 什么时候用​:复杂业务逻辑、批量数据处理、提高性能
  3. 关键命令​:CREATE PROCEDURECALLDROP PROCEDURE

👋 我是数据库小学妹一个用设计师思维学数据库的转行人
​我们一起,把复杂的技术变得简单有趣!**​💕---


本文为个人学习总结,所有命令均在MySQL 8.0环境下验证。存储过程是进阶技能,先掌握基础语法,再考虑实际应用。

相关文章
|
25天前
|
SQL 关系型数据库 MySQL
数据量大查询慢?索引让你的SQL秒级响应!|转行学DB第9天
用生活化比喻(如字典目录)详解索引原理:它通过B+树结构加速查询,避免全表扫描;涵盖创建、查看、删除索引方法,联合索引的最左前缀原则,以及读写平衡等实战要点——让查询从“等几秒”变“秒出”!
数据量大查询慢?索引让你的SQL秒级响应!|转行学DB第9天
|
17天前
|
SQL 关系型数据库 MySQL
SQL优化十大技巧,查询速度提升10倍!
数据库小学妹带你轻松提速SQL!10个实战优化技巧:精简SELECT、善用LIMIT、巧用EXPLAIN、合理建索引、避开函数索引失效、JOIN优于子查询、IN替代OR、批量操作、EXISTS优化大子查询、定期OPTIMIZE。附避坑指南,新手也能秒上手!
|
17天前
|
存储 JSON 缓存
告别数据混乱!数据库设计三范式从入门到实践
数据库小学妹带你轻松入门三范式!用“建房打地基”比喻,讲清1NF(列不可分)、2NF(消除部分依赖)、3NF(消除传递依赖),直击数据冗余、更新异常等痛点。附实战拆表案例与反范式化提醒,助你设计出结构清晰、稳定高效的数据库!
|
1月前
|
SQL 数据库
多表关联查询入门:LEFT JOIN、INNER JOIN一文搞懂|转行学DB第6天
本文通俗易懂地讲解了数据库多表查询的三种JOIN操作:INNER JOIN(内连接)只返回两表匹配的数据,适用于查询交集数据;LEFT JOIN(左连接)保留左表所有记录并匹配右表数据,适用于查询主表完整信息;RIGHT JOIN(右连接)则保留右表所有记录。
|
1月前
|
SQL NoSQL 关系型数据库
数据库分类一次讲清|转行学DB第2天
数据库小学妹(UI转行萌新)用通俗语言拆解数据库分类:从关系型(MySQL/Oracle)、NoSQL(Redis/MongoDB/Cassandra)、NewSQL(TiDB)到2026年爆火的向量数据库(Pinecone/Milvus),按数据模型、部署架构、业务负载三大维度梳理,配场景化案例与选学路径,助新手轻松入门。
|
1月前
|
SQL 关系型数据库 MySQL
WHERE、ORDER BY、LIMIT三大神器,让你的查询精准又高效!
本文介绍了SQL查询中的三大核心语句:WHERE(条件过滤)、ORDER BY(排序)和LIMIT(限制结果数)。通过电商订单查询、用户活跃度分析等实际案例,展示了如何组合使用这些语句实现精准查询。文章还分享了常见避坑技巧(如字符串引号使用、NULL值判断)和性能优化建议(如索引使用、分页查询优化)。
|
19天前
|
SQL 关系型数据库 MySQL
5款好用的免费MySQL客户端,新手必备!
告别枯燥命令行!数据库小学妹精选5款免费MySQL图形化工具:Workbench(官方全能)、phpMyAdmin(免安装Web版)、DBeaver(多库支持)、HeidiSQL(Windows轻量之选)、TablePlus(高颜值跨平台)。小白友好,语法高亮、自动补全、可视化结构一应俱全,助你高效学SQL!
|
23天前
|
SQL 存储 关系型数据库
MySQL视图详解:简化复杂查询的利器|转行学DB第11天
数据库小学妹带你轻松入门视图!视图是“虚拟表”,不存数据,只存SELECT语句,一键封装复杂查询(多表JOIN、聚合等),实现高效复用;还能控制字段暴露、统一数据接口。创建后如普通表使用,简洁安全又省力!
|
16天前
|
SQL 运维 监控
范式设计避坑指南:别让“规范”变成“枷锁”
数据库小学妹带你避开范式设计5大隐形陷阱!从误判主键、隐藏传递依赖,到过度JOIN、盲目反范式、遗留系统改造难题,结合业务平衡与设计思维,教你理性取舍——三范式是起点,不是枷锁。实战避坑,丝滑落地!
|
20天前
|
存储 SQL 关系型数据库
触发器:数据库的"自动响应"机制
数据库触发器是“自动响应”机制:当INSERT/UPDATE/DELETE发生时,无需调用即执行预设逻辑。适用于审计日志、数据校验、自动填充、级联操作等场景。支持BEFORE(可修改数据)和AFTER(常用于记录)两种时机,但需警惕性能影响与调试难度。