MySQL 8.0加载原有触发器报1064语法错误如何解决
问题根因
- 报错核心原因是MySQL 8.0将
PATH新增为系统保留关键字,和你自定义的存储函数名path重名。 - MySQL 5.7版本中
PATH属于非保留字,可以直接作为自定义函数、字段、表名裸用,不需要加转义符,所以你的代码在5.7环境可以稳定运行在各类业务场景。 - 8.0环境下SQL解析器读到裸写的
path时,会优先将其识别为系统保留字,不会匹配你自定义的函数,读到后面跟的括号参数时就会抛出1064语法错误,和你贴出的报错位置完全对应。
修复方案
两种方案二选一即可,都可以彻底解决该报错:
方案1:给自定义函数加反引号转义(改动最小)
所有定义、调用这个自定义函数的位置,用反引号包裹path标识符,明确告知解析器这是用户自定义的函数,不是系统保留字即可。
修改后的核心代码如下:
DELIMITER $$ # # FUNCTIONS # -- @_path DROP FUNCTION IF EXISTS `path`$$ CREATE DEFINER=CURRENT_USER FUNCTION `path`(id INT unsigned, level BOOLEAN) RETURNS VARCHAR(3000) DETERMINISTIC BEGIN ... -- 原有函数逻辑保持不变 END $$ # # TRIGGERS # -- @_root - INSERT MATERIALIZED PATH & RANK DROP TRIGGER IF EXISTS tx_tt_domain_model_root_Bi_0; CREATE TRIGGER tx_tt_domain_model_root_Bi_0 BEFORE INSERT ON tx_tt_domain_model_root FOR EACH ROW BEGIN -- 调用处给path加反引号转义 SET @_relation=if(NEW.relation,`path`(NEW.relation,false),null); SET @_role=if(NEW.role,`path`(NEW.role,false),null); ... -- 其余触发器逻辑保持不变 END $$ ... DELIMITER ;
方案2:重命名自定义函数(长期维护更稳妥)
如果你不想后续维护时每次调用都记得加反引号,可以把自定义函数重命名为非保留字的名称,比如改成get_path、build_materialized_path这类,同步替换所有函数定义、调用位置的名称即可,从根源上避免保留字冲突问题,后续跨版本升级也不容易踩同类坑。
排查提示
跨MySQL大版本升级碰到1064语法错误时,如果报错位置指向你自定义的函数、表、字段名,可以优先对照对应版本的MySQL保留字列表排查是否存在命名冲突,所有和保留字重名的用户标识符,用反引号包裹即可正常使用。
内容的提问来源于stack exchange,提问作者John Miller
相关产品推荐
相关产品推荐

