无法在mysql存储过程上指定表名
我正在为数据库中的东西大量分配新的id号,以便在每个表的开头为一些东西腾出空间。我创建了一个可以工作的过程,但是当我尝试添加输入参数以允许脚本时,它找不到表无法在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
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