我正在尝试执行(迁移)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执行相同的脚本(它们作为Prepared Statements运行,并通过JDBC发送到MariaDB时,一切都按计划进行,没有任何错误。
Java:
connection.prepareStatement(sql).execute();
我真的无法向自己解释为什么会这样。
结果出问题在于不使用分隔符。为了使语句成功解析,应使用分隔符,如下所示:
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似乎添加了自定义定界符或其他内容...