声明游标时使用变量

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使用这个方法?我用你的方法修改了过程,但仍然返回错误。

以上是关于声明游标时使用变量的主要内容,如果未能解决你的问题,请参考以下文章

MySQL游标简介

MySQL游标简介

在 oracle 的游标声明查询中使用变量

基于游标的记录与强引用游标

游标学习

SQL游标怎么用