MySQL的储存过程是一组为了完成特定功能的SQL语句集合,经过编译后存储在数据库中,用户通过指定储存过程的名字并给定参数来调用执行。它可以封装复杂的业务逻辑,避免重复编写相同的SQL代码,同时减少客户端和数据库服务器之间的网络传输次数,提升整体执行效率。

储存过程的基本语法
创建储存过程需要使用CREATE PROCEDURE语句,基本结构如下:
-- 创建储存过程的基本语法
CREATE PROCEDURE 过程名([参数列表])
BEGIN
-- 过程体,包含一组SQL语句
END;
需要注意的是,MySQL默认的分隔符是分号;,而储存过程的过程体中也会包含分号,因此创建储存过程前需要先修改分隔符,避免语法错误。可以使用DELIMITER命令修改分隔符,创建完成后再改回默认的分号。
无参数储存过程示例
下面创建一个简单的无参数储存过程,用来查询当前数据库中的所有用户表信息:
-- 修改分隔符为//
DELIMITER //
-- 创建无参数储存过程
CREATE PROCEDURE GetAllUserTables()
BEGIN
SELECT table_name, table_comment
FROM information_schema.TABLES
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE';
END //
-- 改回默认分隔符
DELIMITER ;
调用这个储存过程只需要使用CALL语句:
-- 调用无参数储存过程 CALL GetAllUserTables();
带参数储存过程示例
储存过程支持三种类型的参数:IN(输入参数,默认类型)、OUT(输出参数)、INOUT(输入输出参数)。下面创建一个带IN和OUT参数的储存过程,用来根据用户输入的用户ID查询对应的用户名,并通过OUT参数返回。
-- 修改分隔符
DELIMITER //
-- 创建带参数的储存过程
CREATE PROCEDURE GetUserNameById(
IN input_id INT, -- 输入参数,用户ID
OUT output_name VARCHAR(50) -- 输出参数,用户名
)
BEGIN
SELECT user_name INTO output_name
FROM user_info
WHERE id = input_id
LIMIT 1;
END //
-- 改回分隔符
DELIMITER ;
调用这个带参数的储存过程时,需要先定义变量接收OUT参数的值:
-- 定义变量接收输出参数 SET @user_name = ''; -- 调用储存过程 CALL GetUserNameById(1, @user_name); -- 查看返回的结果 SELECT @user_name AS user_name;
储存过程的变量与流程控制
在储存过程的过程体中,可以使用DECLARE声明局部变量,也可以使用IF、CASE、WHILE等流程控制语句实现复杂逻辑。下面是一个使用变量和IF判断的示例,用来根据分数判断等级:
DELIMITER //
CREATE PROCEDURE GetScoreLevel(
IN score INT,
OUT level VARCHAR(10)
)
BEGIN
-- 声明局部变量
DECLARE temp_level VARCHAR(10);
-- 流程控制判断
IF score >= 90 THEN
SET temp_level = '优秀';
ELSEIF score >= 60 THEN
SET temp_level = '及格';
ELSE
SET temp_level = '不及格';
END IF;
-- 赋值给输出参数
SET level = temp_level;
END //
DELIMITER ;
调用该储存过程查看结果:
SET @level = ''; CALL GetScoreLevel(85, @level); SELECT @level AS score_level;
储存过程的查看与删除
如果需要查看已经创建的储存过程,可以使用以下语句:
-- 查看当前数据库所有储存过程 SHOW PROCEDURE STATUS WHERE Db = DATABASE(); -- 查看指定储存过程的创建语句 SHOW CREATE PROCEDURE 过程名;
如果不再需要某个储存过程,可以使用DROP PROCEDURE语句删除:
-- 删除储存过程,IF EXISTS避免不存在时报错 DROP PROCEDURE IF EXISTS GetAllUserTables;
使用储存过程的注意事项
- 储存过程在创建时会进行编译,后续调用不需要再次编译,但是修改业务逻辑后需要重新创建或者修改储存过程。
- 储存过程中不能直接使用
USE语句切换数据库,默认操作的是当前调用时所在的数据库。 - 过多的储存过程会增加数据库服务器的维护成本,复杂的业务逻辑建议结合应用层代码实现,避免过度依赖数据库层的逻辑封装。
- 调试储存过程相对困难,MySQL本身没有内置的可视化调试工具,需要借助第三方工具或者打印中间变量来排查问题。