mysql存储函数仅支持返回单个标量值,因其设计限定于标量计算场景;需返回多个值应使用带out参数的存储过程,或用json_object封装为json字符串返回。

MySQL 存储函数不支持返回多个值
MySQL 的 FUNCTION(用户定义函数)语法上只允许一个返回值,且必须在声明时用 RETURNS 明确指定类型(如 INT、VARCHAR(255) 等)。试图在函数体中用多个 RETURN 或返回结果集都会报错,比如:
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration...
这不是权限或配置问题,而是 MySQL 函数的设计限制——它面向的是标量计算场景,不是数据封装或批量输出。
想“返回多个值”?该用存储过程而不是函数
如果需要一次获取多个计算结果(例如同时返回总金额、订单数、平均单价),正确做法是使用 PROCEDURE 配合 OUT 或 INOUT 参数:
-
OUT参数可在调用后读取,相当于“传出多个变量” - 过程内可执行查询、赋值、条件判断,灵活性远超函数
- 调用时需提前声明变量接收,例如:
CALL calc_summary(@total, @cnt, @avg);
注意:不能在 SQL 表达式里直接调用存储过程(比如 SELECT ... FROM t WHERE col = CALL p() 是非法的),这点和函数有本质区别。
替代方案:用 JSON 拼装多个值再返回
如果硬要走函数路线,且调用方能解析 JSON,可用 JSON_OBJECT() 把多个字段打包成单个 JSON 字符串返回:
CREATE FUNCTION get_user_info(uid INT)
RETURNS JSON
READS SQL DATA
BEGIN
RETURN JSON_OBJECT('name', (SELECT name FROM users WHERE id = uid),
'age', (SELECT age FROM users WHERE id = uid),
'city', (SELECT city FROM users WHERE id = uid));
END;
这样函数仍只返回一个值(JSON 类型),但内容结构化。缺点也很明显:
- 调用方必须额外解析 JSON,无法直接用于
WHERE或JOIN - MySQL 5.7+ 才支持原生 JSON 函数,低版本需用字符串拼接(易出错、无类型校验)
- 性能比纯标量操作差,尤其在大结果集上做函数调用时
常见误判点:混淆函数与过程、视图、子查询
很多人以为 SELECT a, b, c FROM t 是“函数返回多值”,其实这是查询结果集,和函数无关。容易踩坑的地方包括:
- 把带多个
SELECT的代码写进FUNCTION体里 → 报错:函数内不允许返回结果集 - 在函数里调用存储过程 → 不允许,函数只能调用其他函数或内置函数
- 试图用
GROUP_CONCAT“模拟多值” → 它只是把多行合并为单个字符串,不是真正多值返回
真正需要多值协作逻辑时,优先拆解为多个独立函数,或直接用存储过程 + 应用层组合,别强塞进单个函数里。










