MariaDB 和 flyway 语法错误,但在 JAVA 中没有

Posted

技术标签:

【中文标题】MariaDB 和 flyway 语法错误,但在 JAVA 中没有【英文标题】:MariaDB and flyway syntax error but not in JAVA 【发布时间】:2020-04-24 00:41:32 【问题描述】:

我正在尝试执行(迁移)SQL 脚本(MariaDB 风格)。 我正在使用 Flyway 来运行脚本。但是,有些脚本会失败...

失败的脚本:

CREATE TRIGGER my_cool_trigger
BEFORE UPDATE ON my_db
FOR EACH ROW
BEGIN
    DECLARE n INT;
    SET n = (SELECT COUNT(uuid) FROM my_db WHERE uuid != NEW.uuid AND a_uuid = NEW.a_uuid AND number = NEW.number AND event_id IS NULL AND t_begin < NEW.t_end AND t_end > NEW.t_begin);
    IF n > 0 THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='Oof. ERROR!!!';
    END IF;
END;

错误信息:

迁移cool_script.sql 失败 -------------------------------------------------- ---- SQL 状态:42000 错误代码:1064 消息:(conn=2661) 你有一个错误 你的 SQL 语法;检查与您的 MariaDB 对应的手册 在第 6 行的 '' 附近使用正确语法的服务器版本

当我尝试通过 Java 执行相同的脚本(它们作为准备好的语句运行,通过 JDBC 发送到 MariaDB)时,一切都按计划进行,没有任何错误。

Java:

connection.prepareStatement(sql).execute();

我真的无法向自己解释为什么会发生这种情况。

【问题讨论】:

*通过 Java *执行相同的脚本是什么意思? Flyway 也是 Java。 它们作为准备好的语句运行 什么“他们”?准备好的语句的具体内容是什么? 它们 = 脚本中包含的语句。 显示您的 Java 代码。 【参考方案1】:

原来问题在于不使用分隔符。 为了使语句能够成功解析,应使用以下分隔符:

DELIMITER //
CREATE TRIGGER my_cool_trigger
BEFORE UPDATE ON my_db
FOR EACH ROW
BEGIN
    DECLARE n INT;
    SET n = (SELECT COUNT(uuid) FROM my_db WHERE uuid != NEW.uuid AND a_uuid = NEW.a_uuid AND number = NEW.number AND event_id IS NULL AND t_begin < NEW.t_end AND t_end > NEW.t_begin);
    IF n > 0 THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='Oof. ERROR!!!';
    END IF;
END//
DELIMITER ;

它在 Java 中工作的原因是 Java prepareStatement 似乎添加了自定义分隔符或其他东西......

【讨论】:

以上是关于MariaDB 和 flyway 语法错误,但在 JAVA 中没有的主要内容,如果未能解决你的问题,请参考以下文章

Flyway 和 MariaDB:SQLException 外键约束的格式不正确

Flyway 命令行:无效参数:-placeholders

使用 Docker 和 Jenkins 自动化 Flyway 迁移

Docker Flyway MySQL 8:客户端不支持服务器请求的身份验证协议。考虑升级 MariaDB 客户端

MariaDB/MySQL 使用更新内部加入 MariaDB 是错误的顺序,但在 MySQL 中是正确的

Laravel GroupBy 在 mysql 中工作,但在 MariaDB 中抛出错误