Синтаксическая ошибка MySQL Flyway

мы используем Flyway с 1 месяца без каких-либо проблем.

Но сегодня я попытался добавить новый скрипт миграции, который очень длинный (более 1500 строк) и столкнулся со странной синтаксической ошибкой MySQL.

Я открыл этот скрипт в MySQL Workbench и не сообщил о синтаксической ошибке, скрипт выполнился без ошибок.

Этот сценарий с именем «V10012__insert-acceptance-testing-event-moment-passed.sql» содержит следующие инструкции.

  • ВСТАВИТЬ оператор 1
  • ВСТАВИТЬ оператор 2
  • ...
  • ВСТАВИТЬ оператор ПОСЛЕДНИЙ - 1
  • ВСТАВЬТЕ оператор ПОСЛЕДНИЙ

Ошибка, о которой сообщает 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. миграции.MigrationException: Миграция на версию 10012 не удалась! Пожалуйста, восстановите резервные копии и откатите базу данных и код!

Об ошибке сообщается в операторе INSERT инструкция LAST.

Но если я инвертирую «оператор INSERT LAST» и «оператор INSERT LAST — 1» в моем сценарии, об ошибке будет сообщено в «операторе INSERT LAST — 1» (который сейчас находится в конце файла). Таким образом, у меня нет ошибки в операторе INSERT LAST, потому что Flyway выполнил его успешно.

Кроме того, если теперь я полностью удалю оператор «ВСТАВИТЬ оператор ПОСЛЕДНИЙ» из сценария «V10012_insert-acceptance-testing-event-moment-passed.sql» и помещу этот оператор в новый файл с именем «V10013_test.sql' flyway успешно выполняет все мои сценарии миграции!

Итак, в чем может быть проблема в моем первоначальном сценарии «V10012__insert-acceptance-testing-event-moment-passed.sql»?

Возможно ли ограничение размера скрипта?

Вот полезная информация о моей среде:

  • В моих сценариях используется много /* */ комментариев
  • Плагин Flyway Maven 1.7
  • Мавен 2.0.3
  • mysql: mysql-коннектор-java: 5.1.21
  • MySQL 5.5.Х
  • Java JDK 1.7.0_09-b05
  • Windows 7

person Baptiste Gaillard    schedule 24.10.2012    source источник


Ответы (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. Если я удалю тему, мне удастся выполнить все мои сценарии миграции.

Например, этот скрипт будет работать:

... 
...

/* 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 statement LAST */
INSERT INTO `table_2` (`id`, `string_3`)
VALUES (
    1,   /* COMMENT 3   */
    'cccc',  /* COMMENT 4   */
    'dddd'
);

Здесь КОММЕНТАРИЙ 3 и КОММЕНТАРИЙ 4 проходят через Flyway, потому что они расположены после ',' и перед строковым значением, но не перед символом ')'.

Надеюсь, это поможет ;-)

person Baptiste Gaillard    schedule 24.10.2012
comment
У меня была аналогичная проблема. В ваших комментариях не было кавычек? - person Læti; 15.02.2013

Это очень маловероятно из-за пролетного пути. Почти наверняка это связано с драйвером MySQL, который использует flyway. С собственным клиентом MySql вы, естественно, предполагаете, что он может обрабатывать любой допустимый синтаксис. Даже «необязательные» блоки комментариев

Одна проблема, о которой я знаю для SURE в драйвере jdbc для MySql, заключается в том, что он не может обрабатывать замену разделителей на лету. Таким образом, триггеры и хранимые процедуры могут быть проблемой, особенно если они были сгенерированы с использованием mysqldump, но затем вы используете приложение Java для повторного приема.

если вы посмотрите здесь и перейдите к 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 что-нибудь, чтобы помочь ему?

person Christian Bongiorno    schedule 03.10.2017