当前位置: 首页 > 知识库问答 >
问题:

声明游标时使用变量

谷梁向荣
2023-03-14
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');

共有1个答案

邰胤
2023-03-14

必须在SQL文本中指定表名;它不能是变量。

为了完成您正在尝试的操作,您将需要动态创建一个包含要执行的SQL文本的字符串。

从任意字符串准备语句:

SET @sqltext := CONCAT('UPDATE ',table_id,' SET entryId = ? WHERE entryId = ?');
PREPARE stmt FROM @sqltext;
EXECUTE stmt USING @new_id, @id;

完成语句后,在循环之后,最佳实践是释放语句,如下所示:

DEALLOCATE PREPARE stmt;

注:

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

 类似资料:
  • 问题内容: 我正在尝试使用EF5从bcontext.Database.SqlQuery执行存储过程。 它抛出一个错误 如果customerNumber是staff,则SP返回,否则返回行。 如何处理? 问题答案: 由于使用的是命名参数,因此必须为要传递的参数指定匹配名称。

  • 问题内容: 我偶然发现了一个奇怪的问题,下面的代码无法编译: 错误(代码是linter推荐的代码)。: 注意,确实使用了该变量。 但是,如果我添加了else块-一切都会按预期编译: 这看起来像是编译器中的错误,还是一个已知问题?任何想法?(我正在使用go 1.11) 编辑:到目前为止的所有被告。按照:https : //golang.org/ref/spec#Short_variable_decl

  • 问题内容: 我正在尝试对MySQL 5.0中的变量进行一些简单的操作,但是我无法完全正常工作。我已经看到了很多(非常!)DECLARE / SET的不同语法,我不确定为什么……在任何情况下,我都可能会混淆它们/选择错误的语法/混合它们。 这是一个失败的最小片段: 我也尝试过使用BEGIN … END包装它;并作为一个程序。在这种情况下,MySQL Workbench会帮助我:第一行显示“’)’附近

  • let和const是JavaScript里相对较新的变量声明方式。 像我们之前提到过的,let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 const是对let的一个增强,它能阻止对一个变量再次赋值。 因为TypeScript是JavaScript的超集,所以它本身就支持let和const。 下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替v

  • 本文向大家介绍C#中使用@声明变量示例(逐字标识符),包括了C#中使用@声明变量示例(逐字标识符)的使用技巧和注意事项,需要的朋友参考一下 在C#中,@符号不仅可以加在字符串常量之前,使字符串不作转义之用,还可以加在变量名之前,使变量名与关键字不冲突,这种用法称为“逐字标识符”。请看下面的代码: 这里使用到@的地方有三处,@class,@static和@bool,如果不加@的话,他们都是关键字,编

  • 问题内容: 最近有人问我这在python中是什么意思: 我不知道。我以前从未见过。我检查了文档,没有类似的东西。一个人的建议是它是静态类型声明,但是在文档中也绝对没有任何内容。 有了以上,如果我 失败了 如果我可以,并且type(char)的结果是。但是它不能是静态声明,因为我可以并且type(char)变为。 所以我来这里是为了收集许多SO霸主的智慧。这意味着什么? 问题答案: 您正在查看变量的