Mysql 声明游标时使用变量

Mysql 声明游标时使用变量,mysql,sql,phpmyadmin,Mysql,Sql,Phpmyadmin,我想将参数传递给过程,并在声明游标时将其用作表名。以下代码返回错误消息:1146-表'db.Table_id'不存在 声明游标时如何使用参数 谢谢 delimiter ;; drop procedure if exists reset_id;; create procedure reset_id(table_id VARCHAR(25)) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE id INT; DECLARE id_

我想将参数传递给过程,并在声明游标时将其用作表名。以下代码返回错误消息:1146-表'db.Table_id'不存在

声明游标时如何使用参数

谢谢

delimiter ;; drop procedure if exists reset_id;; create procedure reset_id(table_id VARCHAR(25)) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE id INT; DECLARE id_new INT; DECLARE getid CURSOR FOR SELECT entryId FROM table_id ORDER BY entryId; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; SET @id_new = 1; OPEN getid; FETCH getid into id; REPEAT UPDATE table_id SET entryId = @id_new WHERE entryId = id; SET @id_new = @id_new + 1; FETCH getid into id; UNTIL done END REPEAT; CLOSE getid; END ;; CALL reset_id('Test'); 修改过程后,仍然返回错误1324-未定义游标:getid。我如何解决这个问题

delimiter ;; drop procedure if exists test2;; create procedure test2(table_id VARCHAR(25)) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE id INT; DECLARE id_new INT; DECLARE stmt1 VARCHAR(1024); DECLARE stmt2 VARCHAR(1024); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; SET @sqltext1 := CONCAT('DECLARE getid CURSOR FOR SELECT entryId FROM ',table_id,' ORDER BY entryId'); PREPARE stmt1 FROM @sqltext1; EXECUTE stmt1; SET @id_new = 1; OPEN getid; FETCH getid into id; REPEAT SET @sqltext2 := CONCAT('UPDATE ',table_id,' SET entryId = ? WHERE entryId = ?'); PREPARE stmt2 FROM @sqltext2; EXECUTE stmt2 USING @new_id, id; SET @id_new = @id_new + 1; FETCH getid into id; UNTIL done END REPEAT; CLOSE getid; END ;; CALL test2('Test');
必须在SQL文本中指定表名;它不能是变量

要完成您试图执行的操作,您需要动态创建一个包含要执行的SQL文本的字符串

要从任意字符串准备语句,请执行以下操作:

SET @sqltext := CONCAT('UPDATE ',table_id,' SET entryId = ? WHERE entryId = ?');
PREPARE stmt FROM @sqltext;
请注意,table_id值被合并到一个字符串变量中,然后PREPARE语句实质上是将该字符串转换为实际的SQL语句

要执行准备好的语句并为绑定变量提供值,可以执行以下操作:

EXECUTE stmt USING @new_id, @id;
DEALLOCATE PREPARE stmt;
您可以多次重新执行已准备好的语句,而无需再次准备。因此,准备工作将在循环之前完成,执行工作可以在循环内部完成

在循环完成语句后,最佳做法是按如下方式取消分配语句:

EXECUTE stmt USING @new_id, @id;
DEALLOCATE PREPARE stmt;
注:


关于表名不是变量的限制实际上适用于SQL语句中的所有标识符,包括表、视图、列、函数等的名称。这些名称都必须是SQL文本中的文字,就像保留关键字一样。

如果要有变量表名,您需要使用准备好的语句,也称为动态SQL。您需要在过程中创建一些语句作为字符串。一个非常相似的问题和答案;谢谢你的回答。我仍然有问题。如何将此方法与游标结合使用?我用您的方法修改了过程,但仍然返回一个错误。