MySQL Коды ошибок 1064 и 2014 в хранимых процедурах - PullRequest
0 голосов
/ 17 марта 2020

Я новичок в MySQL и пытаюсь написать некоторые MySQL хранимые процедуры и сталкиваюсь с некоторыми ошибками, которые я не могу найти исправить.

Простая хранимая процедура для воспроизведения ошибок

DELIMITER //
DROP PROCEDURE IF EXISTS testing;
CREATE PROCEDURE testing(sqlQuery varchar(100))
BEGIN
PREPARE stmt FROM sqlQuery;
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;

Я создаю динамический запрос c sql на сервере приложений и отправляю его в качестве параметра на сервер базы данных MySQL.

Для простоты давайте рассмотрим sqlQuery содержит SELECT * FROM Users.

Когда я впервые выполняю хранимую процедуру в MySQL Workbench, я получаю:

Error Code: 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 'sqlQuery; EXECUTE stmt ; DEALLOCATE PREPARE stmt; END' at line 5

Когда я выполняю ее во второй раз, я получаю:

Error Code: 2014 Commands out of sync; you can't run this command now

Я не могу найти причину этих ошибок. Может кто-нибудь предоставить некоторую информацию? Спасибо.


MySQL: 8.0.19

MySQL Верстак: 8.0.19

Ответы [ 2 ]

2 голосов
/ 17 марта 2020

MYSQL хочет пользовательские переменные для подготовленных операторов :

Оператор, подготовленный в контексте хранимой программы, не может ссылаться на параметры хранимой процедуры или функции или локальные переменные, поскольку они go выходит за рамки, когда программа заканчивается и будет недоступна, если оператор будет выполняться позже вне программы. В качестве обходного пути вместо этого обратитесь к пользовательским переменным, которые также имеют область действия сеанса.

Поэтому вам необходимо промежуточное назначение:

DROP PROCEDURE IF EXISTS testing;

DELIMITER //
CREATE PROCEDURE testing(sqlQuery varchar(100))
BEGIN
    SET @sql = sqlQuery;
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END //

DELIMITER ;

Демонстрация на БД Fiddle

1 голос
/ 17 марта 2020

Вы не можете использовать локальные переменные в хранимых процедурах. Для подготовленных операторов необходимо использовать пользовательские переменные.

Область действия и разрешение локальной переменной

Поскольку локальные переменные находятся в области действия только во время выполнения хранимой программы, ссылки на они не разрешены в подготовленных операторах, созданных в хранимой программе. Подготовленная область действия оператора - это текущий сеанс, а не сохраненная программа, поэтому оператор может быть выполнен после завершения программы, после чего переменные больше не будут находиться в области видимости.

Итак, просто переназначьте параметр для пользовательской переменной.

DELIMITER //
DROP PROCEDURE IF EXISTS testing;
CREATE PROCEDURE testing(sqlQuery varchar(100))
BEGIN
SET @a = sqlQuery;
PREPARE stmt FROM @a;
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;

Это должно работать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...