Mysql 11: 存储过程全解——从创建到使用

存储过程(Stored Procedure)是 MySQL 中预编译在数据库服务器上的 SQL 语句集合,可以封装复杂业务逻辑、减少网络交互、提升执行效率,是数据库开发的核心技能。本文围绕图片中的知识点,从创建、使用、删除到拓展,带你彻底掌握 MySQL 存储过程。


一、核心知识点总览

大类 细分知识点 核心作用
1. 创建存储过程 1) 变量的使用 定义存储过程内的局部变量
2) 变量的修改 修改变量值,实现逻辑计算
3) 流程控制 IF/WHILE/CASE 等控制语句
2. 使用存储过程 调用存储过程,执行预编译逻辑
3. 删除存储过程 删除不再使用的存储过程
4. 拓展一:查看存储过程 3 种查看存储过程的方法
5. 拓展二:修改存储过程 修改存储过程逻辑
6. 拓展三:光标的使用 遍历查询结果集

二、1. 创建存储过程

1.1 基础语法

sql 复制代码
DELIMITER //  -- 临时修改结束符,避免与存储过程内的;冲突
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
    -- 存储过程体:SQL语句、变量、流程控制
END //
DELIMITER ;  -- 恢复默认结束符

关键说明:DELIMITER 用于临时修改语句结束符,因为存储过程体内部需要用 ; 分隔语句,避免提前结束创建。


1.2 变量的使用与修改

(1)变量定义
sql 复制代码
-- 定义局部变量:DECLARE 变量名 数据类型 [DEFAULT 默认值]
DECLARE stu_count INT DEFAULT 0;
DECLARE avg_score DECIMAL(5,2) DEFAULT 0.00;
(2)变量赋值(修改)
sql 复制代码
-- 方式1:直接赋值
SET stu_count = 10;

-- 方式2:查询结果赋值(INTO)
SELECT COUNT(*) INTO stu_count FROM student;
SELECT AVG(score) INTO avg_score FROM score;

1.3 流程控制

(1)IF 条件判断
sql 复制代码
IF 条件 THEN
    -- 执行语句
ELSEIF 条件 THEN
    -- 执行语句
ELSE
    -- 执行语句
END IF;
(2)WHILE 循环
sql 复制代码
WHILE 条件 DO
    -- 循环体
END WHILE;

1.4 完整创建示例

需求:统计学生表人数,根据人数输出不同提示
sql 复制代码
-- 1. 准备测试表
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    age INT NOT NULL
);
INSERT INTO student (name, age) VALUES ('张三',18),('李四',19),('王五',18);

-- 2. 创建存储过程
DELIMITER //
CREATE PROCEDURE count_student()
BEGIN
    -- 1. 定义变量
    DECLARE stu_count INT DEFAULT 0;
    -- 2. 变量赋值:查询学生人数
    SELECT COUNT(*) INTO stu_count FROM student;
    -- 3. 流程控制:IF判断
    IF stu_count > 5 THEN
        SELECT '学生人数超过5人' AS tip;
    ELSEIF stu_count > 0 THEN
        SELECT CONCAT('学生人数为:', stu_count) AS tip;
    ELSE
        SELECT '暂无学生' AS tip;
    END IF;
END //
DELIMITER ;

三、2. 使用存储过程(调用)

语法

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

示例

sql 复制代码
-- 调用刚才创建的存储过程
CALL count_student();

运行结果

tip
学生人数为:3

四、3. 删除存储过程

语法

sql 复制代码
DROP PROCEDURE [IF EXISTS] 存储过程名;

示例

sql 复制代码
-- 删除存储过程
DROP PROCEDURE IF EXISTS count_student;

说明:IF EXISTS 避免存储过程不存在时报错。


五、4. 拓展一:查看存储过程(3 种方法)

方法一:查看所有存储过程

sql 复制代码
SHOW PROCEDURE STATUS WHERE db = DATABASE();

方法二:查看存储过程的创建语句

sql 复制代码
SHOW CREATE PROCEDURE count_student;

方法三:从系统表查询详细信息

sql 复制代码
SELECT * FROM information_schema.ROUTINES 
WHERE ROUTINE_NAME = 'count_student' AND ROUTINE_SCHEMA = DATABASE();

六、5. 拓展二:修改存储过程

MySQL 没有直接修改存储过程的语法,推荐先删除再重建

sql 复制代码
-- 1. 删除旧存储过程
DROP PROCEDURE IF EXISTS count_student;

-- 2. 重新创建修改后的存储过程
DELIMITER //
CREATE PROCEDURE count_student()
BEGIN
    DECLARE stu_count INT DEFAULT 0;
    SELECT COUNT(*) INTO stu_count FROM student;
    -- 修改逻辑:新增年龄统计
    DECLARE avg_age DECIMAL(5,2) DEFAULT 0.00;
    SELECT AVG(age) INTO avg_age FROM student;
    SELECT CONCAT('学生人数:', stu_count, ',平均年龄:', avg_age) AS tip;
END //
DELIMITER ;

七、6. 拓展三:光标的使用(遍历结果集)

光标(Cursor)用于逐行遍历查询结果集,适合批量处理数据。

语法

sql 复制代码
-- 1. 声明光标
DECLARE 光标名 CURSOR FOR 查询语句;
-- 2. 打开光标
OPEN 光标名;
-- 3. 读取数据(FETCH)
FETCH 光标名 INTO 变量列表;
-- 4. 关闭光标
CLOSE 光标名;

完整示例

sql 复制代码
DELIMITER //
CREATE PROCEDURE cursor_demo()
BEGIN
    -- 1. 定义变量
    DECLARE s_id INT;
    DECLARE s_name VARCHAR(20);
    DECLARE done INT DEFAULT FALSE;
    
    -- 2. 声明光标
    DECLARE cur_student CURSOR FOR SELECT id, name FROM student;
    -- 3. 声明循环结束条件
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    -- 4. 打开光标
    OPEN cur_student;
    
    -- 5. 循环遍历
    read_loop: WHILE NOT done DO
        FETCH cur_student INTO s_id, s_name;
        IF NOT done THEN
            -- 处理数据:打印学生信息
            SELECT CONCAT('ID:', s_id, ',姓名:', s_name) AS info;
        END IF;
    END WHILE read_loop;
    
    -- 6. 关闭光标
    CLOSE cur_student;
END //
DELIMITER ;

-- 调用
CALL cursor_demo();

八、核心总结

  1. 存储过程本质:预编译的 SQL 集合,封装业务逻辑,减少网络交互
  2. 核心操作CREATE PROCEDURE 创建、CALL 调用、DROP PROCEDURE 删除
  3. 关键语法DELIMITER 修改结束符、变量定义、流程控制、光标遍历
  4. 适用场景:复杂业务逻辑、批量数据处理、定时任务
相关推荐
Flying pigs~~5 小时前
RAG智慧问答项目
数据库·人工智能·缓存·微调·知识库·rag
misL NITL6 小时前
mysql之如何获知版本
数据库·mysql
许彰午6 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
liang_jy7 小时前
Android SparseArray
android·源码
liang_jy7 小时前
Activity 启动流程扩展篇(一)—— startActivityInner 任务决策全解析
android·源码
2401_832365527 小时前
JavaScript中rest参数(...args)取代arguments的优势
jvm·数据库·python
2301_779622417 小时前
Go语言怎么用信号量控制并发_Go语言semaphore信号量教程【入门】
jvm·数据库·python
2301_766283448 小时前
c++如何将控制台输出保存到文件_cout重定向到txt【详解】
jvm·数据库·python
北极的冰箱8 小时前
MySQL Ver 8.0.41 for macos14.7密码遗忘
数据库·mysql
NPE~8 小时前
[App逆向]脱壳实战
android·教程·逆向·android逆向·逆向分析