**一、存储过程(Stored Procedure)**
**基本概念**
- **定义**:一组预编译的 SQL 语句,可接受参数、执行复杂逻辑,并通过 CALL 语句调用。
- **特点**:
- 不直接返回值,通过 OUT/INOUT 参数输出结果。
- 可包含复杂的流程控制(IF、LOOP、CASE 等)。
- 常用于执行批量操作或事务处理。
**基本语法**
sql
-- 创建存储过程
DELIMITER $$
CREATE PROCEDURE procedure_name ([IN|OUT|INOUT] param1 datatype, ...)
BEGIN
-- SQL 语句和逻辑
END$$
DELIMITER ;
-- 调用存储过程
CALL procedure_name(value1, @output_var);
**示例:计算两数之和**
sql
DELIMITER $$
CREATE PROCEDURE CalculateSum(IN a INT, IN b INT, OUT result INT)
BEGIN
SET result = a + b;
END$$
DELIMITER ;
-- 调用存储过程
CALL CalculateSum(10, 20, @sum);
SELECT @sum; -- 输出:30
**二、函数(Function)**
**基本概念**
- **定义**:一种返回单个值的特殊存储过程,可在 SQL 语句中直接调用。
- **特点**:
- 必须有且只有一个 RETURN 语句返回值。
- 不能修改数据库(如 INSERT、UPDATE),只能查询。
- 可嵌套在其他 SQL 语句中使用(如 SELECT、WHERE)。
**基本语法**
sql
DELIMITER $$
CREATE FUNCTION function_name(param1 datatype, ...)
RETURNS datatype
BEGIN
-- SQL 逻辑
RETURN value;
END$$
DELIMITER ;
-- 调用函数
SELECT function_name(value1);
**示例:计算员工年薪**
sql
DELIMITER $$
CREATE FUNCTION CalculateAnnualSalary(base_salary DECIMAL(10,2), bonus DECIMAL(10,2))
RETURNS DECIMAL(10,2)
DETERMINISTIC -- 声明函数是确定性的(输入相同则输出相同)
BEGIN
RETURN base_salary * 12 + bonus;
END$$
DELIMITER ;
-- 调用函数
SELECT emp_name, CalculateAnnualSalary(salary, bonus) AS annual_salary FROM employees;
**三、主要区别对比**
| **对比项** | **存储过程** | **函数** |
|--------------------|---------------------------------------|---------------------------------------|
| **返回值** | 无直接返回值,通过 OUT 参数输出结果 | 必须返回单个值(通过 RETURN 语句) |
| **调用方式** | 通过 CALL 语句调用 | 可嵌套在 SQL 语句中(如 SELECT、WHERE)|
| **功能** | 可执行复杂操作(如 INSERT、UPDATE) | 只能查询数据,不可修改数据库 |
| **应用场景** | 批量数据处理、事务控制 | 简单计算、数据转换、复杂表达式封装 |
| **确定性要求** | 无强制要求 | 若用于 GROUP BY 等场景需声明 DETERMINISTIC |
**四、使用建议**
1. **选择存储过程**:
- 需要执行 INSERT、UPDATE 等修改操作。
- 需返回多个结果或执行复杂业务逻辑。
- 执行批量操作或事务处理(如转账)。
2. **选择函数**:
- 仅需返回单个计算结果。
- 需在 SQL 语句中频繁调用(如计算平均值、字符串处理)。
- 封装常用表达式以提高代码可读性。
**五、注意事项**
- **权限限制**:创建存储过程/函数需要 CREATE ROUTINE 权限。
- **性能考量**:复杂逻辑建议用存储过程,简单计算用函数。
- **错误处理**:存储过程可使用 DECLARE HANDLER 处理异常,函数不支持。
合理使用存储过程和函数可以提高数据库性能、减少网络传输,并简化应用层代码。