声明游标时使用变量
Posted
技术标签:
【中文标题】声明游标时使用变量【英文标题】:Use variable when declaring cursor 【发布时间】:2014-03-06 05:49:17 【问题描述】:我想将参数传递给过程并将其用作声明游标时的表名。以下代码返回错误消息:#1146 - 表 'db.table_id' 不存在。
声明游标时如何使用参数?
谢谢
分隔符;; 如果存在则删除程序 reset_id;; 创建过程 reset_id(table_id VARCHAR(25)) 开始 DECLARE done INT DEFAULT FALSE; 声明 id INT; 声明 id_new INT; DECLARE getid CURSOR FOR SELECT entryId FROM table_id ORDER BY entryId; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 设置@id_new = 1; 打开getid; 将 getid 提取到 id 中; 重复 UPDATE table_id SET entryId = @id_new WHERE entryId = id; 设置@id_new = @id_new + 1; 将 getid 提取到 id 中; 直到完成 END REPEAT; 关闭 getid; 结尾 ;; 调用 reset_id('Test');修改过程后,仍然返回错误#1324 - Undefined CURSOR: getid。我该如何解决这个问题?
分隔符;; 如果存在则删除程序 test2;; 创建过程 test2(table_id VARCHAR(25)) 开始 DECLARE done INT DEFAULT FALSE; 声明 id INT; 声明 id_new INT; 声明 stmt1 VARCHAR(1024); 声明 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'); 从@sqltext1 准备stmt1; 执行 stmt1; 设置@id_new = 1; 打开getid; 将 getid 提取到 id 中; 重复 SET @sqltext2 := CONCAT('UPDATE ',table_id,' SET entryId = ? WHERE entryId = ?'); 从@sqltext2 准备stmt2; 使用@new_id,id执行stmt2; 设置@id_new = @id_new + 1; 将 getid 提取到 id 中; 直到完成 END REPEAT; 关闭 getid; 结尾 ;; 调用 test2('测试');【问题讨论】:
如果想要有变量表名,需要使用prepared statements(也称为动态SQL)。 您需要在过程中创建一些语句作为字符串。一个非常相似的问题和答案; ***.com/questions/3646412/… 【参考方案1】:必须在 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;
您可以多次重新执行准备好的语句,而无需再次准备。因此,PREPARE 将在您的循环之前完成,EXECUTE 可以在循环内完成。
一旦你完成了语句,在循环之后,最好的做法是像这样释放语句:
DEALLOCATE PREPARE stmt;
注意:
表名不是变量的限制实际上适用于 SQL 语句中的所有标识符,包括表名、视图名、列名、函数名等。这些都必须是 SQL 文本中的文字,就像保留关键字可以。
【讨论】:
感谢您的回答。我仍然有问题。如何结合CURSOR使用这个方法?我用你的方法修改了过程,但仍然返回错误。以上是关于声明游标时使用变量的主要内容,如果未能解决你的问题,请参考以下文章