无法在mysql存储过程上指定表名

无法在mysql存储过程上指定表名,mysql,stored-procedures,Mysql,Stored Procedures,我正在为数据库中的东西大量分配新的id号,以便在每个表的开头为一些东西腾出空间。我创建了一个可以工作的过程,但是当我尝试添加输入参数以允许脚本时,它找不到表 delimiter | CREATE PROCEDURE changeID ( IN in_table_name varchar(64)) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE a,b INT DEFAULT 800000; DECLARE cur1 CURSOR FO

我正在为数据库中的东西大量分配新的id号,以便在每个表的开头为一些东西腾出空间。我创建了一个可以工作的过程,但是当我尝试添加输入参数以允许脚本时,它找不到表

delimiter |
CREATE PROCEDURE changeID 
( IN in_table_name varchar(64)) 
BEGIN 
  DECLARE done INT DEFAULT FALSE;
  DECLARE a,b INT DEFAULT 800000;
  DECLARE cur1 CURSOR FOR SELECT id  FROM in_table_name ORDER BY id;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
  FETCH cur1 INTO b;
    IF done THEN
      LEAVE read_loop;
    END IF;
        UPDATE in_table_name SET id = a + 1 where id = b;
        SET a = a+1;

END LOOP;
  CLOSE cur1;
END; 
|
delimiter ;
当我使用call changeID'users'运行此命令时,我得到错误:

[Err] 1146 - Table 'databaseName.in_table_name' doesn't exist
我希望使用这样一个简单的命令列表进行循环,这样它就可以在无人参与的情况下运行,而不是在每次执行之间手动更改in_table_名称:

call changeID('users');
call changeID('appointments');
call changeID('groups');

您不能在查询中动态传递表名,但是,您可以连接字符串,然后将其作为语句执行。你当然要小心,并确保这些数据已被消毒等。我无法测试这一点,但这种效果应该让你去

...
END IF;

SET @Query = CONCAT('UPDATE ',in_table_name,' SET `id` = ',a+1,' WHERE `id`=',b);
PREPARE stmt FROM @Query;
EXECUTE stmt;
...

KChason让我朝着正确的方向开始了,但我必须走得更远一点,才能从这里的提示开始第一部分的工作:


谢谢你,我正在尝试使用你在光标选择中教给我的东西,但是在这之后的任何一行我都会得到一个错误:SET@in_table\u name=in_table\u name varchar50;我试过使用和不使用varchar,DECLARE而不是SET,有什么原因我不能在循环之外设置它吗?我没有看到你在评论中提到的行。为什么要重置变量?您会遇到哪些错误?你为什么不更新你的问题,这样它就可以很好地格式化呢?这一行给出了我正在处理的表中行的id,你帮助的另一部分是执行。声明cur1游标用于按id从in_表_名称顺序中选择id;
DROP PROCEDURE
IF EXISTS `workingversion`;

delimiter |

CREATE PROCEDURE `workingversion` (IN tableName VARCHAR(100))
BEGIN

DECLARE done INT DEFAULT 0 ;
DECLARE a,
 b INT DEFAULT 800000 ;
DROP VIEW IF EXISTS v1; 
SET @stmt_text = CONCAT("CREATE VIEW v1 AS SELECT id FROM ",    tableName,  " ORDER BY id") ; 
PREPARE stmt
FROM
    @stmt_text ; EXECUTE stmt ; DEALLOCATE PREPARE stmt ;
BEGIN

DECLARE cur1 CURSOR FOR SELECT * FROM v1 ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET done = 1 ; OPEN cur1 ;
REPEAT
    FETCH cur1 INTO b ;
IF NOT done THEN
SET @Query = CONCAT('UPDATE ',tableName,' SET `id` = ',a+1,' WHERE `id`=',b);
PREPARE stmt FROM @Query;
EXECUTE stmt;

        SET a = a+1;
END
IF ; UNTIL done
END
REPEAT
    ; CLOSE cur1 ;
END ;
END