Сегодня в этом разделе документации MySQL я узнал, что подготовленные операторы не могут быть выполнены в хранимых функциях, но, начиная с версии MySQL 5.0.13, они могут выполняться в хранимых процедурах.
Сегодня я собирал хранимую процедуру и сначала подумал, что, возможно, было бы интересно сделать в ней оператор INSERT как подготовленный оператор. Однако, несмотря на то, что это возможно (я использую MySQL 5.5.14),? маркер параметра в строке оператора заставил MySQL выдать синтаксическую ошибку.
Я собрал несколько упрощенных примеров, используя тот же самый синтаксис, который я использовал для подготовленного оператора INSERT. Я надеюсь, что у меня просто есть синтаксическая ошибка где-то, что я просто не поймал. Первый блок ниже - это процедура, которая работает, то есть использует стандартный синтаксис CONCAT (ваша строка запроса).
DROP PROCEDURE IF EXISTS TestConc;
DELIMITER $$
CREATE Procedure TestConc()
BEGIN
SET @sql := CONCAT('CREATE TABLE Foo (FooID INT) ENGINE = InnoDB');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @tn := 'Foo';
SET @sql := CONCAT('INSERT INTO ', @tn, ' VALUES (5)');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
$$
DELIMITER ;
При вызове процедуры с этим кодом происходит ожидаемое; 5 сохраняется в поле FooID вновь созданной таблицы Foo. Однако, если мы изменим строки между двумя директивами DEALLOCATE PREPARE на это:
SET @tn := 'Foo';
SET @sql := 'INSERT INTO ? VALUES (5)';
PREPARE stmt FROM @sql;
EXECUTE stmt USING @tn;
Мы получаем ошибку, которая говорит нам, чтобы проверить синтаксис оператора рядом с '? ЦЕННОСТИ (5) '.
Разве нельзя заменить маркер параметра на имя таблицы? Я не пытался делать что-то вроде «ВЫБРАТЬ? ОТ Foo ', чтобы увидеть, будет ли это работать еще. Кроме того, и я не знаю, важно ли это, я пробовал это использовать MySQL Workbench 5.2.35 CE, а не командную строку.
У меня нет особой необходимости запускать запросы как подготовленные операторы внутри процедур ATM, я просто хочу убедиться, что у меня есть правильный синтаксис для этого, если мне когда-нибудь понадобится.