普通用户执行create function必失败,因需同时满足:①拥有create routine和alter routine权限;②log_bin_trust_function_creators=1(须写入my.cnf并重启);③函数体必须声明deterministic/no sql/reads sql data。

普通用户直接执行 CREATE FUNCTION 一定会失败,不是语法或账号密码问题,而是权限和配置双重卡死——必须同时满足三项条件才能成功。
为什么 CREATE FUNCTION 总报 ERROR 1418?
这个错误信息(This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA...)只是表层提示。真正拦住你的有三道关:
- 用户缺少
CREATE ROUTINE权限(注意:不是CREATE FUNCTION,这个权限根本不存在) - MySQL 启用了 binlog(即配置了
--log-bin),但未设置log_bin_trust_function_creators = ON - 用户还缺
ALTER ROUTINE—— 否则后续改函数、删函数会立刻报错
必须在 my.cnf 中配 log_bin_trust_function_creators
这个参数不能用 SET GLOBAL 动态修改,必须写进配置文件并重启 MySQL:
[mysqld] log_bin_trust_function_creators = ON
重启后生效。不重启=白设。生产环境若需主从复制,请确保只对可信账号启用该参数,而不是全局放行。
授予用户 CREATE ROUTINE 和 ALTER ROUTINE 权限
权限范围要匹配实际使用场景:
- 如果只在
app_db库里建函数:GRANT CREATE ROUTINE, ALTER ROUTINE ON `app_db`.* TO 'dev_user'@'localhost'; - 如果需要跨库调用其他库的表,函数本身仍可定义在
app_db,但执行时会检查目标库表权限——所以还要额外给对应SELECT或UPDATE权限 - 切勿用
ON *.*授予全局 ROUTINE 权限,除非你明确知道后果
函数创建后,调用它还需要 EXECUTE 权限
创建完函数不等于能用。其他用户(包括创建者自己,如果连接时用的是不同账号)想调用,必须显式授权:
- 只给某一个函数:
GRANT EXECUTE ON FUNCTION app_db.calc_tax TO 'reporter'@'%'; - 给整个库下所有函数:
GRANT EXECUTE ON FUNCTION app_db.* TO 'api_user'@'192.168.5.%'; - 权限变更后,已有连接不会自动更新,要么重连,要么执行
FLUSH PRIVILEGES;(仅当直接改了 mysql 系统表才必须)
最容易被忽略的是:函数体里访问了 otherdb.orders,但用户没有 otherdb 的 SELECT 权限——这时报错不是权限不足,而是“表不存在”或“拒绝访问”,排查方向容易跑偏。











