我们在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
答案 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解析器中的一个错误?
我今天没有时间对它进行测试,但似乎只有在以下情况下才会出现此错误:
如果一个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
);
我必须逃离Name
和Position
让flyway接受它,即使我的bash脚本迭代执行这些也没有问题。
也许我可以告诉Java驱动程序有什么帮助它?