MySQL自定义函数(Stored Function)就是你自己封装的一段可复用逻辑,定义后能像 NOW()、CONCAT() 这些内置函数一样,直接在 SQL 里调用,比如 SELECT get_score_level(86)。它主要用于轻量的计算、格式化和数据转换,核心特点就是必须返回一个值,而且只能返回一个。
在MySQL中,很多人会混淆**自定义函数(UDF,用户自定义函数)**和存储过程,二者虽然都属于数据库可编程对象,但使用场景、语法限制、调用方式差异很大。
内置函数如SUM()、DATE_FORMAT()可以直接拿来用,但如果业务有固定的计算逻辑、格式化规则,反复写重复SQL就很繁琐,这时就可以自己编写MySQL自定义函数,封装逻辑,一行调用。
注意:MySQL自定义函数有返回值,必须返回单个值;不能返回结果集,这是和存储过程最核心的区别。
|
1 2 3 4 5 6 7 8 9 |
DELIMITER // CREATE FUNCTION 函数名(参数名 参数类型) RETURNS 返回值类型 [DETERMINISTIC] BEGIN -- 函数业务逻辑 RETURN 返回的数据; END // DELIMITER ; |
关键字说明:
|
1 2 3 4 |
-- 查看数据库下所有自定义函数 SHOW FUNCTION STATUS WHERE Db = '你的数据库名'; -- 删除自定义函数 DROP FUNCTION IF EXISTS 函数名; |
需求:传入分数,返回等级。比如 >=90优秀,>=80良好,>=60及格,其余不及格。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
DELIMITER // CREATE FUNCTION get_score_level(score INT) RETURNS VARCHAR(20) DETERMINISTIC BEGIN DECLARE level VARCHAR(20); IF score >= 90 THEN SET level = '优秀'; ELSEIF score >= 80 THEN SET level = '良好'; ELSEIF score >= 60 THEN SET level = '及格'; ELSE SET level = '不及格'; END IF; RETURN level; END // DELIMITER ; |
调用方式(和内置函数一样,放在select里)
|
1 2 3 |
SELECT get_score_level(86); -- 结合表查询 SELECT name, score, get_score_level(score) AS level FROM student; |
需求:传入字符串,去掉多余空格,转为大写返回
|
1 2 3 4 5 6 7 8 |
DELIMITER // CREATE FUNCTION str_upper_trim(str VARCHAR(255)) RETURNS VARCHAR(255) DETERMINISTIC BEGIN RETURN UPPER(TRIM(str)); END // DELIMITER ; |
调用:
|
1 |
SELECT str_upper_trim(' hello mysql '); |
| 对比项 | 自定义函数Function | 存储过程Procedure |
|---|---|---|
| 返回值 | 必须有且只能返回单个值 | 无返回值,可以用OUT输出多个参数 |
| 调用方式 | select 函数() | call 存储过程() |
| 参数类型 | 仅支持IN输入参数 | 支持IN/OUT/INOUT三种参数 |
| 返回结果集 | 不能返回多行结果集 | 可以查询返回结果集 |
| 事务 | 不建议在函数内使用事务 | 支持事务、复杂业务逻辑 |
| 使用场景 | 简单计算、字段格式化、转换 | 批量DML、复杂多步骤业务 |
一句话总结:简单计算、字段转换用自定义函数;多表更新、批量操作、复杂业务流程用存储过程。
MySQL自定义函数适合封装轻量、无副作用的计算转换逻辑,使用简单,调用方式和内置函数保持一致。但它不是万能的,千万不要把复杂业务全部塞进函数,尤其是大数据量查询场景,很容易引发性能问题。开发前分清函数和存储过程的适用边界,才能发挥它的价值。