execute权限是执行存储过程和函数的必要条件,必须显式授予,仅select等dml权限无法调用;mysql 5.7中需分别用grant execute on procedure db.sp_name和on function db.func_name语法授权,且show create procedure还需额外grant show_routine。

EXECUTE 权限是执行存储过程和函数的必要条件
在 MySQL 5.7 中,仅授予 SELECT、INSERT 等数据操作权限,**无法执行存储过程或函数**。必须显式授予 EXECUTE 权限,否则调用时会报错:ERROR 1370 (42000): execute command denied to user ... for routine ...。
该权限属于「数据库对象级别权限」,可按库、按过程/函数名精细控制,不依赖全局权限(如 ALL PRIVILEGES)。
-
EXECUTE权限本身不包含查看定义(SHOW CREATE PROCEDURE)的能力,后者需额外授权(见下文) - 即使用户对底层表有全部 DML 权限,没有
EXECUTE仍不能CALL prc_name()或SELECT func_name() - 若存储过程内含
SQL SECURITY DEFINER(默认),实际执行时检查的是DEFINER用户的权限,而非调用者——此时给调用者授EXECUTE即可,无需再授表级权限
GRANT EXECUTE ON PROCEDURE 和 FUNCTION 的语法差异
MySQL 5.7 要求对存储过程和函数**分别授权**,且对象名写法不同:
- 对存储过程:用
PROCEDURE db_name.sp_name格式,例如GRANT EXECUTE ON PROCEDURE testdb.p_insert TO 'appuser'@'%'; - 对函数:用
FUNCTION db_name.func_name格式,例如GRANT EXECUTE ON FUNCTION testdb.f_count_total TO 'appuser'@'%'; - 若想批量授权整个数据库下的所有过程和函数,可用
GRANT EXECUTE ON testdb.* TO 'appuser'@'%';——注意这不是通配符匹配,而是 MySQL 对数据库级EXECUTE的特殊支持 - 不能写成
GRANT EXECUTE ON testdb.p_insert() TO ...(括号非法)或GRANT EXECUTE ON testdb.`p_insert` TO ...(反引号非必需,但加了也不报错)
为什么 SHOW CREATE PROCEDURE 仍报错?你漏了 SHOW_ROUTINE 权限
授予 EXECUTE 后,用户能正常调用,但执行 SHOW CREATE PROCEDURE p_name 仍可能失败,错误为:ERROR 1370 (42000): show create procedure command denied to user ...。
这是因为查看定义需要独立的 SHOW_ROUTINE 权限(MySQL 5.7 引入,替代旧版对 mysql.proc 的直接查询):
-
GRANT SHOW_ROUTINE ON testdb.* TO 'appuser'@'%';—— 授予该库下所有过程/函数的定义查看权 -
GRANT SHOW_ROUTINE ON *.* TO 'appuser'@'%';—— 全局生效(慎用,暴露所有库的过程结构) -
SHOW_ROUTINE是全局权限类型(只能用*.*或db_name.*),不支持精确到单个过程名 - 该权限不影响执行,只影响元数据可见性;生产环境应避免授予
*.*,优先用库级粒度
MySQL 5.7 权限生效前必须 FLUSH PRIVILEGES 吗?
通常不需要。使用 GRANT 语句授权后,权限立即生效(MySQL 5.7 默认启用动态权限加载)。只有以下情况才需手动刷新:
- 直接修改
mysql.user、mysql.db等系统表后(不推荐) - 使用旧版客户端连接且未重新认证(极少见)
- 你明确看到
SHOW GRANTS FOR 'user'@'host'输出未更新,此时执行FLUSH PRIVILEGES;可强制重载
更可靠的做法是:授权后立刻用目标用户连接并测试 CALL 或 SELECT,比依赖 FLUSH 更直接。容易被忽略的是:权限变更**不影响已存在的连接**,新权限只对后续新建连接生效。











