1. 什么是存储过程?
存储过程(Stored Procedure)是一组为了完成特定功能的**预编译的SQL语句集合**。它像一个存储在数据库服务器中的“脚本”或“函数”,有一个名字,当需要执行它所定义的操作时,调用它的名字即可。
2. 为什么需要存储过程?
封装性:隐藏复杂业务逻辑,只暴露调用接口。
高性能:预编译,首次编译后直接执行,减少了解析和优化开销。
减少网络流量:客户端只需发送一条调用指令,而非大量原始SQL。
增强安全性与数据完整性:可作为安全接口,限制对底层数据的直接访问,并在服务器端集中处理数据规则。
代码复用与维护:一次编写,多处调用。逻辑变更只需修改存储过程,无需修改所有应用程序代码。
3. 存储过程的基本语法
a. 创建存储过程
DELIMITER // -- 临时修改分隔符,避免过程中的 `;` 被误认为结束
CREATE PROCEDURE procedure_name (
[IN | OUT | INOUT] parameter_name parameter_type, ...
)
BEGIN
存储过程体:包含SQL语句和流程控制语句
SELECT * FROM some_table;
... 更多逻辑
END //
DELIMITER ; -- 将分隔符改回分号
`IN` (默认):输入参数,调用者传入值给存储过程。
`OUT`:输出参数,存储过程通过它返回值给调用者。
`INOUT`:既是输入也是输出参数。
b. 调用存储过程
CALL procedure_name([parameter, ...]);
c. 删除存储过程
DROP PROCEDURE IF EXISTS procedure_name;
4. 一个简单的示例
假设我们有一个 `students` 表,需要创建一个存储过程来根据城市查询学生。
DELIMITER // CREATE PROCEDURE GetStudentsByCity(IN city_name VARCHAR(50)) BEGIN SELECT * FROM students WHERE city = city_name; END // DELIMITER ;
调用存储过程
CALL GetStudentsByCity('北京');
5. 存储过程的缺点(重要补充)
虽然优点很多,但也必须谨慎使用,它有以下缺点:
调试困难:不同于高级语言,存储过程的调试工具和体验较差。
移植性差:严重依赖特定的数据库系统(如MySQL),其语法和功能与其他数据库(如Oracle, PostgreSQL)不兼容,迁移成本高。
版本管理复杂:存储过程的代码存储在数据库中,与应用程序代码(通常用Git等工具管理)分离,使得版本控制和协同开发更复杂。
服务器压力:复杂的逻辑在数据库服务器上执行,会消耗更多的CPU和内存资源,可能影响数据库的整体性能(这与您提到的“高性能”不矛盾,“高性能”指执行速度快,但资源消耗确实更大)。
6. 存储过程 vs. 应用程序代码
这是一个常见的架构选择问题:
在数据库中处理(存储过程):适合数据密集型操作(如复杂的报表生成、大数据量迁移、批量更新),减少网络往返。
在应用程序中处理:适合业务逻辑复杂的操作(涉及多个系统、复杂计算、外部API调用),利于调试、扩展和移植。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程