Mysql 带ALTER表的存储过程
我需要在同一MySQL服务器上不同数据库中的两个表之间同步自动增量字段。希望是创建一个存储过程,管理员的权限允许web用户运行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
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
。我想它是有效的。。。但这并不好。