MySQL不支持GRANT EXECUTE ON PROCEDURE语法,唯一合法方式是GRANT EXECUTE ON db_name.*(仅8.0.16+支持),需先授USAGE权限,且仅覆盖存储过程和函数。

不能用 GRANT EXECUTE ON PROCEDURE *.* 或 GRANT EXECUTE ON *.* 授予“所有存储过程”的权限——MySQL 不支持这种写法,会直接报错 ERROR 1064。
GRANT EXECUTE ON db_name.* 是唯一合法的“所有过程”授权方式
MySQL 中没有“所有存储过程”这个独立权限范围,但 db_name.* 是被明确支持的语法,它表示该数据库下所有可执行对象(包括存储过程和函数),且未来新建的过程也自动包含在内。
- ✅ 正确:
GRANT EXECUTE ON `myapp`.* TO 'api_user'@'10.20.%'; - ❌ 错误:
GRANT EXECUTE ON PROCEDURE *.* TO ...(语法不识别) - ❌ 错误:
GRANT EXECUTE ON myapp.* TO ...(缺反引号,当库名含下划线或为关键字时可能失败) - ⚠️ 注意:
myapp.*不包含视图、表或触发器,只覆盖PROCEDURE和FUNCTION
为什么 GRANT EXECUTE ON myapp.* 后 CALL 还报 ERROR 1370
错误提示看起来像权限没给,实际多是以下三个原因导致:
- 用户连接时 host 不匹配:比如授权的是
'api_user'@'10.20.%',但客户端连的是'api_user'@'localhost',MySQL 视为两个不同账号 - 过程定义里用了
SQL SECURITY DEFINER(默认),而DEFINER账号(如'dba'@'localhost')已失效,或该账号本身对内部表无 SELECT 权限 - MySQL 8.0+ 启用了角色,但
EXECUTE权限是授给角色的,用户没执行SET ROLE role_name;
GRANT EXECUTE ON myapp.* 的兼容性与前提条件
这个语法在 MySQL 5.7 中不可用,必须满足版本和前置权限要求:
- ✅ 仅 MySQL 8.0.16+ 稳定支持
GRANT EXECUTE ON db_name.* - ✅ 必须先授予数据库级
USAGE权限:GRANT USAGE ON `myapp`.* TO 'api_user'@'10.20.%';(跳过这步,后续EXECUTE授权会失败) - ❌ MySQL 5.7 执行该语句会报
ERROR 1064 (42000),此时只能升级或改用GRANT ALL PRIVILEGES ON myapp.*(不推荐,违背最小权限) - ?
FLUSH PRIVILEGES;在常规GRANT后不需要手动执行(5.7.6+ 自动刷新)
想让所有过程都按调用者权限运行?不能靠授权解决
GRANT EXECUTE ON myapp.* 只控制“能不能调”,不改变过程内部 SQL 的权限校验逻辑。如果所有过程都需基于调用者权限检查(比如 api_user 必须自己有 SELECT 权限才能读表),那每个过程都得显式声明 SQL SECURITY INVOKER:
ALTER PROCEDURE `myapp`.`get_user_info` SQL SECURITY INVOKER;
但这需要 ALTER ROUTINE 权限,普通用户通常没有,必须 DBA 操作。漏掉任何一个过程,它仍以 DEFINER 身份执行,就可能因定义者权限异常而静默失败。


















