Во время эксперимента с установкой mysqlsh, мы обнаружили проблему с тем, как он анализирует хранимые процедуры.
Первая мысль всегда: это наш код? Мы проверили файл, запустив его как файл сценария через MySQL Workbench. Он отлично работал в MySQL Workbench, но неоднократно терпел неудачу при запуске из утилиты mysqlsh. На следующем этапе сократите код до небольшого тестового примера, повторите его и запишите ошибку, если она реплицируется. Тестовый пример в файле test.sql генерирует следующие ошибки при запуске из утилиты mysqlsh:
MySQL localhost:33060+ ssl studentdb SQL > > source test.sql Query OK, 0 rows affected (0,0003 sec) ERROR: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE PROCEDURE test ( pv_input1 CHAR(12) , pv_input2 CHAR(19)) MODIFIES SQL ' at line 2 Query OK, 0 rows affected (0.0002 sec) Query OK, 0 rows affected (0,0003 sec) ERROR: 1305: PROCEDURE studentdb.test does not exist
Тот же файл генерирует эту серию успешных сообщений при запуске в качестве файла сценария из MySQL Workbench:
Preparing... Importing test.sql... Finished executing script Statement CREATE PROCEDURE test pv_input1 One Operation completed successfully
Для тех, кому интересно просмотреть тестовый пример, вот он:
-- Сбросьте разделитель так, чтобы точка с запятой могла использоваться в качестве оператора и Терминатора блока. DELIMITER $$ SELECT 'CREATE PROCEDURE test' AS "Statement"; CREATE PROCEDURE test ( pv_input1 CHAR(12) , pv_input2 CHAR(19)) MODIFIES SQL DATA BEGIN SELECT CONCAT(pv_input1,', ',pv_input2) AS message; END; $$ -- Сбросьте стандартный разделитель, чтобы точка с запятой работала как команда выполнения. DELIMITER ; -- Вызовите процедуру тестирования. CALL test('One','Two');
Ответ в ошибке объяснил разницу в поведении между MySQL Workbench и средой MySQL Shell (mysqlsh). MySQL Workbench использует клиент MySQL, который поддерживает несколько клиентских операторов с опцией CLIENT_MULTI_STATEMENTS. Признавая это, оператор SELECT записи журнала должен переместиться в позицию перед установкой DELIMITER, например:
-- Установите метку для файла журнала. SELECT 'CREATE PROCEDURE test' AS "Statement"; -- Сбросьте разделитель так, чтобы точка с запятой могла использоваться в качестве оператора и Терминатора блока. DELIMITER $$ CREATE PROCEDURE test ( pv_input1 CHAR(12) , pv_input2 CHAR(19)) MODIFIES SQL DATA BEGIN SELECT CONCAT(pv_input1,', ',pv_input2) AS message; END; $$ -- Сбросьте стандартный разделитель, чтобы точка с запятой работала как команда выполнения. DELIMITER ; -- Вызовите процедуру тестирования. CALL test('One','Two');
Новый тестовый пример отправляет только один оператор за раз. Запрос на ведение журнала представлен точкой с запятой, а процедура проверки — двойным символом доллара ($$).
Итак, мы правильно определили разницу в поведении парсинга между MySQL Workbench и MySQL Shell. Кажется, что это различие по дизайну, но документация MySQL Shell не может объяснить, что он не может управлять несколькими операторами. Мы надеемся, что определение этого сэкономит время другим.
Это также верно , что программное обеспечение поддерживает MySQL клиента TEE и NOTEE в файлы журналов записи. К сожалению, MySQL Shell (mysqlsh) не поддерживает синтаксис TEE и NOTEE.