【SQL】深入理解MySQL存储过程:从入门到实战
一、什么是存储过程(Stored Procedure)
存储过程 是一组预编译的 SQL 语句的集合,存储在数据库服务器端,可以被多次调用。它类似于编程语言中的“函数”或“方法”,可以接收参数、执行逻辑、返回结果。
✅ 优点:
- 提高性能:SQL 语句被预编译,执行效率更高。
- 减少网络传输:客户端只需调用存储过程名称,无需发送大量 SQL 语句。
- 增强安全性:可限制用户直接操作表,通过存储过程控制访问权限。
- 代码复用:一次编写,多次调用。
- 便于维护:逻辑集中于数据库端,便于统一管理。
❌ 缺点:
- 调试困难(相比应用层代码)。
- 移植性差(不同数据库语法不兼容)。
- 增加数据库服务器负担。
二、存储过程的基本语法
DELIMITER $$CREATE PROCEDURE 存储过程名([参数列表])
BEGIN-- SQL 语句
END $$DELIMITER ;
🔍 说明:
DELIMITER $$
:修改语句结束符为$$
,避免;
提前结束定义。CREATE PROCEDURE
:创建存储过程的关键字。BEGIN ... END
:定义存储过程的代码块。DELIMITER ;
:恢复默认结束符为分号。
三、无参存储过程示例
示例:查询所有学生信息
DELIMITER $$CREATE PROCEDURE GetAllStudents()
BEGINSELECT * FROM student;
END $$DELIMITER ;
调用方式:
CALL GetAllStudents();
✅ 注意:调用时使用
CALL
关键字。
四、带参存储过程
参数类型:
类型 | 说明 |
---|---|
IN | 输入参数(默认),调用时传入值 |
OUT | 输出参数,存储过程返回值给调用者 |
INOUT | 既可输入又可输出 |
示例 1:IN 参数 —— 根据 ID 查询学生
DELIMITER $$CREATE PROCEDURE GetStudentById(IN sid INT)
BEGINSELECT * FROM student WHERE id = sid;
END $$DELIMITER ;
调用:
CALL GetStudentById(1);
示例 2:OUT 参数 —— 返回学生总数
DELIMITER $$CREATE PROCEDURE GetStudentCount(OUT total INT)
BEGINSELECT COUNT(*) INTO total FROM student;
END $$DELIMITER ;
调用:
CALL GetStudentCount(@count);
SELECT @count AS 学生总数;
✅
INTO total
:将查询结果赋值给 OUT 参数。
示例 3:INOUT 参数 —— 给数值加 10
DELIMITER $$CREATE PROCEDURE AddTen(INOUT num INT)
BEGINSET num = num + 10;
END $$DELIMITER ;
调用:
SET @n = 5;
CALL AddTen(@n);
SELECT @n; -- 输出 15
五、查看与删除存储过程
1. 查看所有存储过程
SHOW PROCEDURE STATUS WHERE db = '数据库名';
2. 查看某个存储过程的定义
SHOW CREATE PROCEDURE 存储过程名;
3. 删除存储过程
DROP PROCEDURE IF EXISTS 存储过程名;
✅ 推荐使用
IF EXISTS
避免报错。
六、注意事项与最佳实践
- 命名规范:建议使用
sp_
或proc_
前缀,如sp_GetAllStudents
。 - 参数命名:避免与字段名冲突,可加
p_
前缀,如p_id
。 - 错误处理:高级用法中可结合
DECLARE HANDLER
处理异常。 - 事务控制:可在存储过程中使用
START TRANSACTION
、COMMIT
、ROLLBACK
。 - 调试技巧:使用
SELECT
输出中间变量辅助调试。
七、实际应用场景
场景 | 说明 |
---|---|
数据统计 | 每日/每月报表生成 |
批量操作 | 批量插入、更新、删除 |
复杂业务逻辑 | 多表关联、条件判断、循环处理 |
权限隔离 | 只允许调用存储过程,禁止直接访问表 |
存储过程是数据库编程的重要组成部分,合理使用可显著提升系统性能与安全性。