MariaDB运行迁移脚本创建自定义SQL函数时出现多个语法错误
问题原因
- 核心诱因是第三方服务器使用的SQL执行工具/迁移框架不支持
DELIMITER指令:DELIMITER是MySQL/MariaDB命令行客户端的专属控制命令,不属于标准SQL语法,绝大多数JDBC客户端、自动化迁移工具(如Flyway、Liquibase、自研升级脚本)默认不识别该指令,会直接将其当作普通SQL执行报错。 - 同时这类工具默认会按分号
;作为SQL语句分隔符拆分脚本,导致你的自定义函数代码被拆成多个不完整的SQL片段依次执行:比如第一句执行到DECLARE diff INT;就结束,后续语句无法识别已经声明的diff变量,也无法匹配IF/ELSE/END等逻辑块的语法结构,就会出现你遇到的各类报错。 - 本地执行正常是因为你用的是官方
mysql命令行工具,原生支持DELIMITER指令,会先调整分隔符,将整个函数定义作为单条完整SQL提交给服务端执行。
修复方案
方案1:适配执行工具(推荐,不需要修改原有函数逻辑)
根据你用的执行工具做对应配置即可:
- 若使用Flyway迁移:在脚本头部添加注释
-- delimiter //,Flyway会自动识别自定义分隔符,不需要额外修改配置 - 若使用Liquibase迁移:在
sql标签中指定splitStatements=false属性,关闭自动按分号拆分的规则 - 若使用自研JDBC脚本执行:在JDBC连接串中添加参数
allowMultiQueries=true,同时不要自行按分号拆分脚本,将整段SQL一次性提交执行
方案2:重写函数为单行语法(通用兼容,所有执行环境都支持)
你当前的函数逻辑非常简单,可以直接去掉BEGIN END复合语句块,完全不需要修改分隔符,重写后的脚本如下:
CREATE FUNCTION second_diff(dateColA timestamp, dateColB timestamp) RETURNS INT RETURN TIMESTAMPDIFF(SECOND, dateColA, IFNULL(dateColB, CURRENT_TIMESTAMP)); UPDATE version SET current_version = '1.0.1';
重写后完全不需要DELIMITER相关语句,任何执行工具都可以直接正常运行。
内容的提问来源于stack exchange,提问作者tzudemom
相关产品推荐
相关产品推荐

