Flyway MySQL语法错误

时间:2012-10-24 10:07:56

标签: mysql jdbc flyway

我们在1个月内使用Flyway而没有遇到任何问题。

但是,今天我尝试添加一个非常长(超过1500行)的新迁移脚本,并遇到奇怪的MySQL语法错误。

我在MySQL Workbench中打开了这个脚本,没有报告语法错误,脚本执行没有错误。

这个名为'V10012__insert-acceptance-testing-event-moment-passed.sql'的脚本包含以下说明。

  
      
  • INSERT语句1
  •   
  • INSERT声明2
  •   
  • ...
  •   
  • INSERT语句LAST - 1
  •   
  • INSERT语句最后
  •   

MySQL报告的错误如下:

  

[错误]引起的   com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:你有一个   SQL语法错误;查看与您的手册相对应的手册   MySQL服务器版本,用于在'INSERT INTO附近使用正确的语法   video_feedback(id,youtube_video_id)VALUES(1102,/ * id * /'   在第232行[错误]   com.googlecode.flyway.core.migration.MigrationException:迁移到   版本10012失败了!请恢复备份并回滚数据库   和代码!

在“INSERT语句LAST”语句中报告错误。

但如果我在我的脚本中反转'INSERT语句LAST'和'INSERT语句LAST - 1',则会在'INSERT语句LAST - 1'(现在位于文件末尾)上报告错误。所以我在'INSERT语句LAST'中没有错误,因为Flyway成功执行了它。

此外,如果现在我从脚本'V10012_ insert-acceptance-testing-event-moment-passed.sql'中完全删除'INSERT语句LAST'语句,并将此语句放入名为'V10013的新文件中 _test.sql'flyway成功执行了我的所有迁移脚本!

那么,在我最初的'V10012__insert-acceptance-testing-event-moment-passed.sql'脚本中可能出现什么问题?

是否存在可能的脚本大小限制?

以下是有关我的环境的有用信息:

  
      
  • 我的脚本使用了大量的/ * * / comments
  •   
  • Flyway Maven Plugin 1.7
  •   
  • Maven 2.0.3
  •   
  • 的MySQL:MySQL的连接器的Java:5.1.21
  •   
  • MySQL 5.5.X
  •   
  • Java JDK 1.7.0_09-b05
  •   
  • Windows 7
  •   

2 个答案:

答案 0 :(得分:2)

我终于找到了问题的原因。

在我的剧本中,我有:

... 
...

/* INSERT statement LAST - 1 */ 
INSERT INTO `table_1` (`id`, `string_1`, `string_2`)
VALUES (
    1, 
    'aaa',   /* COMMENT 1*/
    'bbb'    /* COMMENT 2*/
);

/* INSERT statement LAST */
INSERT INTO `table_2` (`id`, `string_3`)
VALUES (
    1,       /* COMMENT 3   */
    'cccc'   /* COMMENT 4    */
);

问题似乎在评论2和评论4上。如果我删除主题flyway成功执行我的所有迁移脚本。

例如,此脚本将起作用:

... 
...

/* INSERT statement LAST - 1 */ 
INSERT INTO `table_1` (`id`, `string_1`, `string_2`)
VALUES (
    1, 
    'aaa',   /* COMMENT 1*/
    'bbb'    
);

/* INSERT statement LAST */
INSERT INTO `table_2` (`id`, `string_3`)
VALUES (
    1,   /* COMMENT 3   */
    'cccc'   
);

那么,也许这是Flyway解析器中的一个错误?

我今天没有时间对它进行测试,但似乎只有在以下情况下才会出现此错误:

  • 我们在VARCHAR(或我认为的其他字符串列类型)之后发表评论
  • 此评论位于')'字符
  • 之前

如果一个SQL脚本中存在多个insert语句,则此问题似乎只能重现。

此外,我认为未放在')'之前的评论是正确的,例如:

/* INSERT statement LAST */
INSERT INTO `table_2` (`id`, `string_3`)
VALUES (
    1,   /* COMMENT 3   */
    'cccc',  /* COMMENT 4   */
    'dddd'
);

这里的评论3和评论4在Flyway中传递,因为它们位于','之后,在字符串值之前,但它们没有放在')'字符之前。

希望这可以提供帮助; - )

答案 1 :(得分:1)

由于飞路,这种情况不太可能发生。这几乎肯定与flyway正在使用的MySQL驱动程序有关。使用MySql本机客户端,您自然会认为它可以处理任何合法语法。即使是'可选'评论块

我知道mySql的jdbc驱动程序中的 SURE 的一个问题是它无法处理即时分隔符交换。因此触发器和存储过程可能是一个问题,特别是如果它们是使用mysqldump生成的,但随后您使用Java应用程序重新摄取。

如果您查看here并转到spring.datasource.separator,您会看到系统范围(基本上)设置为;

现在想象一下脚本中这一行的表现如何:

DELIMITER ;;
CREATE FUNCTION `int2vancode`(id BIGINT(20)) RETURNS varchar(255)
BEGIN
    DECLARE num VARCHAR(10);
    DECLARE length INT;
    SET num = conv(id, 10, 36);
    SET length = char_length(num);

    return CONCAT(conv(length -1 , 10, 36), num);
END ;;
DELIMITER ;

java驱动程序是愚蠢的,并不解释任何这些语句,即使DELIMITER语句明确意味着客户端

我现在遇到一个问题,本机客户端执行每个脚本没有问题,但是flyway说我有一个语法错误,即使是intellij也看不到。

**更新**

我解决了我的问题,它或多或少地证实了我所看到的问题: 我有一个创建表:

CREATE TABLE `Position` (
  PositionID INT NOT NULL AUTO_INCREMENT,
  `Name` varchar(200) COLLATE utf8_unicode_ci NOT NULL
);

我必须逃离NamePosition让flyway接受它,即使我的bash脚本迭代执行这些也没有问题。

也许我可以告诉Java驱动程序有什么帮助它?