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

时间:2018-02-20 16:33:59

标签: 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 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_name

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

2 个答案:

答案 0 :(得分:1)

您无法在查询中动态传递表名,但是,您可以连接一个字符串,然后将其作为语句执行。你当然要小心并确保这些数据已被消毒等等。我无法对此进行测试,但是这样的事情会让你前进。

...
END IF;

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

https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html

答案 1 :(得分:0)

KChason让我开始朝着正确的方向前进,但我不得不更进一步,让第一部分从这里的提示开始工作:https://forums.mysql.com/read.php?98,138495,138908#msg-138908

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