Mysql 带ALTER表的存储过程

Mysql 带ALTER表的存储过程,mysql,stored-procedures,Mysql,Stored Procedures,我需要在同一MySQL服务器上不同数据库中的两个表之间同步自动增量字段。希望是创建一个存储过程,管理员的权限允许web用户运行altertable[db1].[TABLE]AUTO_INCREMENT=[num]而不授予它权限(这就是SQL注入的味道) 我的问题是在创建存储过程时收到错误。这是MySQL不允许的吗 如果存在同步自动增量,则删除程序 创建过程集自动增量(tableName VARCHAR(64),inc INT) 开始 更改表tableName AUTO_INCREMENT=in

我需要在同一MySQL服务器上不同数据库中的两个表之间同步自动增量字段。希望是创建一个存储过程,管理员的权限允许web用户运行
altertable[db1].[TABLE]AUTO_INCREMENT=[num]而不授予它权限(这就是SQL注入的味道)

我的问题是在创建存储过程时收到错误。这是MySQL不允许的吗


如果存在同步自动增量,则删除程序
创建过程集自动增量(tableName VARCHAR(64),inc INT)
开始
更改表tableName AUTO_INCREMENT=inc
结束;

问题似乎是您需要更改分隔符。它认为
altertable
行是函数的结尾。试试这个:

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 ;

我想您会发现不能将数据定义语言语句放入存储过程中。一个可能的例外是创建临时表。我已经在MySQL手册中搜索了关于这一点的更多信息;它说存储过程可能包含一个语句列表,但没有定义它的含义。但我认为情况就是这样。

继续讨论对……的评论。。。是的,你可以使用事先准备好的陈述。但是你必须使用
CONCAT
来创建句子,而不是使用
PREPARE。。。从…

以下是一个可行的解决方案:

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;


我从迈克尔·麦克劳克林的文章中学到了这一点

哦,我不认为你真的可以使用一个变量作为表名,所以你可能需要为每个你想修改的表制定不同的程序……为了简洁起见,我实际上删除了分隔符。我尝试了你的两个例子,仍然得到以下错误<代码>您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以了解使用near'inc的正确语法;“在第5行结束”
等等,您根本不能将变量用作表名?!?我听说可以使用事先准备好的声明。这听起来有道理吗?MsSQL手册给出了一个例子:
PREPARE stmt_name FROM“SELECT name FROM Country WHERE code=?”。这是我第一次听说他们。我试着从“选择*从?限制10”中准备tmp\u stmt它给了我同样的错误。所以,看来准备好的声明(无论如何,在我的简短尝试中)也不会起作用。我正在设置过程,以便对3个具有相同结构的表执行某些操作,最后我不得不写入:
IF(tablename='table\u name\u 1'),然后为另外两个表选择*FROM table\u name\u 1
和另一个
IF
。我想它是有效的。。。但这并不好。