mysql 5.7 不支持 grant execute on function db.func_name 语法,会报 error 1064;必须使用 grant execute on db.* 授予库级权限,才能调用其中的函数。

MySQL 5.7 中不能对单个函数用 GRANT EXECUTE ON FUNCTION
直接执行 GRANT EXECUTE ON FUNCTION db.func_name TO 'user'@'%' 在 MySQL 5.7 及更早版本会报错:ERROR 1064 (42000): You have an error in your SQL syntax。这不是权限没配对,而是语法根本不被识别——5.7 不支持按具体函数名授权,只支持库级或全局级 EXECUTE。
真正有效的做法是授库级 EXECUTE 权限
想让某个用户能调用 db.f_count_total,你必须给它授予整个数据库的 EXECUTE 权限:
GRANT EXECUTE ON `db`.* TO 'user'@'%';
这条语句生效后,该用户就能调用 db 下所有已存在的函数和存储过程(包括 f_count_total),但无法创建、修改或删除它们(那需要 CREATE ROUTINE 或 ALTER ROUTINE)。
注意事项:
- 库名必须用反引号包裹(如
`db`),避免库名含特殊字符或关键字时出错 - 不能写成
GRANT EXECUTE ON db.f_count_total()(括号非法)或GRANT EXECUTE ON db.`f_count_total`(5.7 不认) - 如果用户还需查看函数定义(
SHOW CREATE FUNCTION f_count_total),得额外加GRANT SHOW_ROUTINE ON `db`.* TO 'user'@'%'
为什么 CALL 或 SELECT func_name() 还报 EXECUTE command denied?
即使 GRANT EXECUTE ON `db`.* 执行成功,调用仍失败,常见原因不是权限语句本身,而是上下文不匹配:
- 用户连接的 host 和授权的 host 不一致:比如授的是
'user'@'localhost',但应用连的是'user'@'127.0.0.1'(MySQL 视为两个账号) - 函数内部查询了其他库的表(如
SELECT ... FROM otherdb.t_log),但用户没有otherdb的SELECT权限 - 函数定义中用了
SQL SECURITY DEFINER(默认),而定义者账号(如'admin'@'localhost')已失效或权限不足,MySQL 会 fallback 到调用者权限校验,此时仍需用户有底层表权限
MySQL 8.0.16+ 支持单函数授权,但有前提
8.0.16 及以上版本确实支持 GRANT EXECUTE ON FUNCTION db.func_name,但必须先确保用户已有 USAGE 权限:
GRANT USAGE ON `db`.* TO 'user'@'%';<br>GRANT EXECUTE ON FUNCTION `db`.`f_count_total` TO 'user'@'%';
不过,这种细粒度授权在生产中极少使用,因为:
- 运维成本高:每新增一个函数就得补一条
GRANT - 权限不可继承:不能通过角色批量管理,也不能跨库自动生效
- 排查困难:错误仍统一报
EXECUTE command denied,不会提示“函数不存在”或“函数无权调用”,容易误判
最易维护的做法,还是把要开放的函数集中放在专用库(如 api_functions),然后只对该库授 EXECUTE —— 这样既可控,又不用反复改权限语句。











