我需要在同一MySQL服务器上的不同数据库中的两个表之间同步auto_increment字段。希望创建一个存储过程,其中管理员的权限将允许Web用户运行ALTER TABLE [db1].[table] AUTO_INCREMENT = [num];
而不赋予其权限(这只是SQL注入的气味)。
我的问题是我在创建商店程序时收到错误。这是MySQL不允许的吗?
DROP PROCEDURE IF EXISTS sync_auto_increment;
CREATE PROCEDURE set_auto_increment (tableName VARCHAR(64), inc INT)
BEGIN
ALTER TABLE tableName AUTO_INCREMENT = inc;
END;
答案 0 :(得分:3)
要继续讨论有关Chibu的answer的评论......是的,您可以使用预备语句。但您必须使用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;
我从Michael McLaughlin的文章Prepared Statement Failure中学到了这一点。
答案 1 :(得分:0)
问题似乎是您需要更改分隔符。它认为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 ;
答案 2 :(得分:0)
我认为您会发现无法将数据定义语言语句放入存储过程中。可能的例外是CREATE TEMPORARY TABLE。我已经在MySQL手册中搜索了关于这一点的更多信息;它说存储过程可能包含一个statement_list,但没有定义这意味着什么。但我认为就是这种情况。