报ERROR 1418是因为binlog启用时,MySQL要求函数必须声明DETERMINISTIC、NO SQL或READS SQL DATA,否则拒绝创建;解决需按实际行为添加对应特性子句或临时设置log_bin_trust_function_creators=1。

MySQL 自定义函数不能在普通用户权限下直接创建,必须拥有 CREATE ROUTINE 权限,且默认情况下 log_bin_trust_function_creators 为 OFF —— 这会导致创建失败并报错 ERROR 1418。
为什么执行 CREATE FUNCTION 报 ERROR 1418?
这是 MySQL 的安全限制:当二进制日志(binlog)启用时,系统要求确定性函数(DETERMINISTIC)、或显式声明为 READS SQL DATA/NO SQL,否则拒绝创建。常见错误信息是:
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled
解决方法不是简单加 DETERMINISTIC(它必须真实符合函数行为),而是按需选择以下之一:
- 如果函数确实不读写数据,加上
DETERMINISTIC或NO SQL - 如果函数会查表,必须加
READS SQL DATA - 临时关闭校验(仅测试环境):
SET GLOBAL log_bin_trust_function_creators = 1
创建带参数和返回值的标量函数
MySQL 函数只能返回单个值(标量),不能返回结果集。定义时需明确指定参数类型、返回类型、特性子句。例如,写一个截取手机号后 4 位的函数:
DELIMITER $$ CREATE FUNCTION get_phone_tail(p_phone VARCHAR(20)) RETURNS VARCHAR(4) READS SQL DATA DETERMINISTIC BEGIN RETURN RIGHT(TRIM(p_phone), 4); END$$ DELIMITER ;
注意点:
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
-
DELIMITER $$是必需的,否则分号会被误认为语句结束 -
READS SQL DATA可省略(本例没查表),但若函数内含SELECT ... FROM就必须声明 -
DETERMINISTIC表示相同输入总得相同输出;若含NOW()、RAND()等,必须改用NOT DETERMINISTIC
调用自定义函数与常见陷阱
函数可直接用于 SELECT、WHERE、ORDER BY 中,但不能用于存储过程体外的赋值语句(如 SET @x = myfunc(...) 是合法的,但 SELECT myfunc(...) INTO @x 更通用)。
典型误用:
- 在函数体内调用存储过程(不允许)
- 试图返回多列或多行(函数不支持,该用视图或存储过程)
- 参数名和表字段名冲突导致
Unknown column错误(建议参数加前缀如p_) - 函数中使用未声明的变量(MySQL 函数不支持
DECLARE变量以外的自由变量)
查看、修改与删除函数
函数属于数据库对象,元数据存于 mysql.proc,但推荐用标准方式管理:
- 查看已创建函数:
SHOW FUNCTION STATUS WHERE Db = 'your_db'; - 查看函数定义:
SHOW CREATE FUNCTION get_phone_tail; - 删除函数:
DROP FUNCTION IF EXISTS get_phone_tail; - 修改函数:没有
ALTER FUNCTION,必须先DROP再CREATE
函数体内的逻辑变更无法热更新,且函数被视图或其它函数引用时,DROP 会失败(报错 ERROR 1305),需先检查依赖。









