一、 为什么使用存储过程?

简化数据库操作:将多步 SQL 操作封装为一个命令,调用更方便。
提升执行效率:一次编译,可重复运行,能够减少网络传输开销。
降低出错概率:将业务逻辑集中在 MySQL 存储过程中处理,避免应用程序重复编写代码而产生错误。
二、 创建存储过程的基本语法
CREATE PROCEDURE <过程名> ( [过程参数[,…] ] )
BEGIN
<过程体>
END;
1. 过程名 (`<过程名>`)
命名规则与普通标识符基本一致。
建议使用具有明确含义的名称(如 `GetUserOrders`, `CalculateMonthlyRevenue`),便于维护和理解。
不要使用 MySQL 内置函数名作为存储过程名称。
2. 过程参数 (`[IN | OUT | INOUT] <参数名> <类型>`)**
这是 MySQL 创建存储过程时实现灵活调用的关键部分。
| 参数类型 | 关键字 | 说明 | 补充说明 |
|---|---|---|---|
| 输入参数 | IN | 调用者向存储过程传入参数值(默认模式,可省略)。参数在过程体内部通常是只读的。 | 最常用 |
| 输出参数 | OUT | 存储过程通过该参数向调用者返回结果。传入的初始值通常会被忽略,在过程体中可写入新值。 | 用于返回结果 |
| 输入/输出参数 | INOUT | 同时具备 IN 和 OUT 的作用。调用者先传入值,存储过程处理后再返回修改后的值。 | 双向传递 |
注意:参数名称尽量不要与数据表字段名相同,否则容易引发歧义或不可预知的错误。
3. 过程体 (`<过程体>`)
过程体中包含存储过程需要执行的核心 SQL 语句。
简单的存储过程可以只有一条 SQL 语句。
复杂的过程体则可以包含变量声明、流程控制(IF, CASE, LOOP)以及异常或错误处理等内容。
通常使用 `BEGIN ... END` 组成一个完整的复合语句块。
三、 至关重要的 `DELIMITER` 命令
大家都知道,MySQL 默认在遇到分号 `;` 时就会执行当前语句。但在 MySQL 存储过程的过程体内部,往往会包含多条以 `;` 结尾的 SQL 语句。这样一来,MySQL 就可能在遇到第一个分号时,误判 `CREATE PROCEDURE` 语句已经结束。
解决方法:临时修改命令行客户端中的语句结束分隔符。
操作步骤:
1. 先声明新的分隔符(例如 `//` 或 `$$`)。
DELIMITER //
2. 再编写完整的 CREATE PROCEDURE 语句。此时过程体中的分号 `;` 不会触发提前执行。
CREATE PROCEDURE MyProcedure()
BEGIN
SELECT * FROM table1;
SELECT * FROM table2; -- 这里的分号是安全的
END //
整个存储过程定义以新的分隔符 `//` 结束
3. 最后将分隔符恢复为分号。
DELIMITER ;
四、 创建存储过程示例
例1:创建无参数的存储过程 `ShowStuScore`
(从学生成绩表中查询所有学生成绩)
DELIMITER // 步骤1:修改分隔符
CREATE PROCEDURE ShowStuScore()
BEGIN
过程体中可以写入一条或多条 SQL 语句
SELECT * FROM tb_students_score;
END //
DELIMITER ; 步骤3:恢复分隔符
调用存储过程
CALL ShowStuScore();
例2:创建带有输入(IN)参数的存储过程 `GetScoreByStu`
(根据学生姓名查询对应成绩)
DELIMITER //
CREATE PROCEDURE GetScoreByStu(IN name VARCHAR(30))
BEGIN
SELECT student_score FROM tb_students_score
WHERE student_name = name; -- 这里的 `name` 是参数,不是字段名
END //
DELIMITER ;
调用存储过程并传入参数
CALL GetScoreByStu('Dany');
例3:创建带有输出(OUT)参数的存储过程 `GetMaxScore`
(查询最高分,并通过参数返回结果)
DELIMITER //
CREATE PROCEDURE GetMaxScore(OUT max_score INT)
BEGIN
将查询结果通过 INTO 赋值给输出参数
SELECT MAX(student_score) INTO max_score FROM tb_students_score;
END //
DELIMITER ;
调用存储过程
先定义一个用户变量(@ms)用于接收 OUT 参数返回的值
CALL GetMaxScore(@ms);
查看返回结果
SELECT @ms AS 'Max Score';
五、 权限要求
要在 MySQL 中创建存储过程,当前用户必须拥有 `CREATE ROUTINE` 权限。
以上内容已经覆盖了 MySQL 创建存储过程最基础、最核心的知识点。下一步可以继续深入学习:
1. 变量使用:如何在过程体中定义并使用局部变量(`DECLARE`)。
2. 流程控制:使用 `IF...THEN...ELSE`、`CASE`、`WHILE...DO`、`LOOP` 等实现更复杂的业务逻辑。
3. 查看与删除:可通过 `SHOW PROCEDURE STATUS` 查看存储过程信息,并使用 `DROP PROCEDURE <过程名>` 删除指定存储过程。
