MySQL存储过程是数据库服务器端的一组预编译SQL语句集合,用户可以通过指定存储过程的名字并传入对应参数来调用执行,避免了多次发送SQL语句到服务器的网络开销,同时预编译的特性也能提升执行效率。

存储过程的基础语法
创建存储过程需要使用CREATE PROCEDURE语句,基本语法结构如下:
-- 创建存储过程基础语法
CREATE PROCEDURE 存储过程名([参数模式] 参数名 参数类型)
BEGIN
-- 存储过程逻辑体,可包含多条SQL语句
END;
其中参数模式有三种:
- IN:输入参数,调用时传入值,存储过程内部可读取该值,默认模式
- OUT:输出参数,存储过程执行完成后会向外返回结果值
- INOUT:输入输出参数,调用时传入值,执行完成后可返回修改后的值
由于MySQL默认语句结束符是分号;,而存储过程逻辑体内部也会用到分号,所以需要临时修改语句结束符,避免语法冲突,常用DELIMITER命令修改:
-- 修改语句结束符为$$
DELIMITER $$
-- 创建存储过程
CREATE PROCEDURE test_proc()
BEGIN
SELECT 'Hello MySQL Procedure';
END $$
-- 恢复语句结束符为分号
DELIMITER ;
无参数存储过程示例
创建一个查询用户表中所有用户信息的无参数存储过程:
-- 修改结束符
DELIMITER $$
-- 创建存储过程
CREATE PROCEDURE get_all_users()
BEGIN
-- 查询用户表所有数据
SELECT id, username, age FROM user;
END $$
-- 恢复结束符
DELIMITER ;
调用存储过程使用CALL语句:
-- 调用无参数存储过程 CALL get_all_users();
带IN参数的存储过程
创建根据用户输入的年龄查询对应年龄用户信息的存储过程:
DELIMITER $$
CREATE PROCEDURE get_users_by_age(IN target_age INT)
BEGIN
SELECT id, username, age FROM user WHERE age = target_age;
END $$
DELIMITER ;
调用时传入对应参数:
-- 查询年龄为20的用户 CALL get_users_by_age(20);
带OUT参数的存储过程
创建查询用户表中总用户数的存储过程,通过OUT参数返回结果:
DELIMITER $$
CREATE PROCEDURE get_user_count(OUT total_count INT)
BEGIN
-- 统计用户总数并赋值给输出参数
SELECT COUNT(*) INTO total_count FROM user;
END $$
DELIMITER ;
调用时需要定义变量接收OUT参数的值:
-- 定义用户变量接收结果 SET @count = 0; -- 调用存储过程 CALL get_user_count(@count); -- 查看返回结果 SELECT @count AS total_user_count;
带条件判断和循环的存储过程
创建一个存储过程,根据用户传入的分数判断等级,同时插入多条测试数据:
DELIMITER $$
CREATE PROCEDURE handle_score(IN input_score INT, OUT level VARCHAR(10))
BEGIN
-- 条件判断逻辑
IF input_score >= 90 THEN
SET level = '优秀';
ELSEIF input_score >= 60 THEN
SET level = '合格';
ELSE
SET level = '不合格';
END IF;
-- 循环插入5条测试数据
DECLARE i INT DEFAULT 1;
WHILE i <= 5 DO
INSERT INTO score_log(score, level) VALUES(input_score, level);
SET i = i + 1;
END WHILE;
END $$
DELIMITER ;
调用该存储过程:
SET @level_result = ''; CALL handle_score(85, @level_result); SELECT @level_result AS score_level;
存储过程的管理操作
查看存储过程
查看数据库中所有存储过程的基本信息:
-- 查看当前数据库所有存储过程 SHOW PROCEDURE STATUS WHERE Db = DATABASE();
查看指定存储过程的创建语句:
-- 查看存储过程get_all_users的创建语句 SHOW CREATE PROCEDURE get_all_users;
修改存储过程
MySQL不支持直接修改存储过程的逻辑内容,如果需要修改存储过程,只能先删除再重新创建:
-- 删除存储过程
DROP PROCEDURE IF EXISTS get_all_users;
-- 重新创建修改后的存储过程
DELIMITER $$
CREATE PROCEDURE get_all_users()
BEGIN
SELECT id, username, age, create_time FROM user;
END $$
DELIMITER ;
删除存储过程
删除存储过程使用DROP PROCEDURE语句,建议加上IF EXISTS避免存储过程不存在时报错:
-- 删除存储过程 DROP PROCEDURE IF EXISTS get_users_by_age;
存储过程的优缺点
| 优点 | 缺点 |
|---|---|
| 预编译执行,性能更高;减少网络传输,降低服务器压力;逻辑封装在数据库端,便于复用和维护 | 不同数据库语法差异大,可移植性差;存储过程调试难度大,逻辑复杂时不易排查问题;过度使用会增加数据库服务器的计算压力 |
存储过程适合用在逻辑相对固定、需要重复执行、且对性能有一定要求的业务场景,比如数据统计、批量数据操作等,不建议把过于复杂的业务判断逻辑全部放在存储过程中实现。