Хранимая процедура с ALTER TABLE - PullRequest
2 голосов
/ 26 марта 2010

Мне нужно синхронизировать поля auto_increment между двумя таблицами в разных базах данных на одном и том же сервере MySQL. Мы надеялись создать хранимую процедуру, в которой права администратора позволяли бы веб-пользователю запускать ALTER TABLE [db1].[table] AUTO_INCREMENT = [num]; без предоставления ему разрешений (это просто пахнет SQL-инъекцией).

Моя проблема в том, что я получаю ошибки при создании процедуры сохранения. Это что-то, что не разрешено MySQL?

DROP PROCEDURE IF EXISTS sync_auto_increment;<br> CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)<br> BEGIN<br> ALTER TABLE tableName AUTO_INCREMENT = inc;<br> END;

Ответы [ 3 ]

3 голосов
/ 05 июля 2012

Чтобы продолжить обсуждение комментариев Чибу ответ ... да, вы можете использовать подготовленные заявления. Но вы должны использовать CONCAT для создания предложения вместо PREPARE ... FROM ....

Вот рабочее решение:

DROP PROCEDURE IF EXISTS set_auto_increment;
DELIMITER //
CREATE PROCEDURE set_auto_increment (_table VARCHAR(64), _inc INT)
BEGIN
    DECLARE _stmt VARCHAR(1024);
    SET @SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT =  ', _inc);
    PREPARE _stmt FROM @SQL;
    EXECUTE _stmt;
    DEALLOCATE PREPARE _stmt;
END//
DELIMITER;

Я узнал эту форму из статьи Ошибка подготовленного заявления Майкла Маклафлина.

0 голосов
/ 09 июля 2010

Я думаю, вы обнаружите, что не можете поместить операторы языка определения данных в хранимую процедуру. Возможное исключение будет CREATE TEMPORARY TABLE. Я искал руководство MySQL для получения дополнительной информации по этому вопросу; он говорит, что хранимая процедура может содержать список Statement_List, но нигде не определяет, что это значит. Но я думаю, что это так.

0 голосов
/ 26 марта 2010

Кажется, проблема в том, что вам нужно изменить разделитель. Он считает, что строка Alter table является концом функции. Попробуйте это:

DROP PROCEDURE IF EXISTS sync_auto_increment;
DELIMITER //
CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)
BEGIN
ALTER TABLE tableName AUTO_INCREMENT = inc;
END//

DELIMITER ;

Иногда mysql по-прежнему требователен к тому, чтобы разрешить вам использовать хранимые процедуры, поэтому вы можете попробовать это, если по-прежнему не можете запустить его:

DROP PROCEDURE IF EXISTS sync_auto_increment;
DELIMITER //
CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)
DETERMINISTIC
READS SQL DATA
BEGIN
ALTER TABLE tableName AUTO_INCREMENT = inc;
END//

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