游标提取 Returns 空
Cursor Fetch Returns Null
问题很明显,但我尝试了很多方法来修复它,包括使用与 table 字段不同的变量名称。从游标中获取的值总是 returns null。分配给游标提取的值是相同的数据类型 (int(11))。我正在做的是将从光标的 select table 中获取的 key_id 值分配给 @my_key_id int(11) 变量,但它一直为 null。
declare my_key_id int(11); /*variable that will be assigned from the value in cursor*/
DECLARE done INT DEFAULT FALSE; /*for cursor break*/
DECLARE cr_cursor cursor for select key_id from tmp_valuesss; /*cursor declaration*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /*break thingy*/
open cr_cursor;
read_loop: LOOP
IF done THEN
LEAVE read_loop;
END IF;
select @my_key_id;
FETCH cr_cursor INTO my_key_id;
END LOOP;
close cr_cursor;
您将用户变量(带有 @
符号的变量)误认为是局部变量(带有 DECLARE 的变量)。
您的用户变量从未设置,因此始终为空。
此外,取消分配任何准备变量。
Fetch
已上移以出现在 LOOP 的开头。
drop procedure if exists calculate_thingy;
delimiter $$
CREATE PROCEDURE calculate_thingy
(
IN table_name VARCHAR(100)
)
BEGIN
DECLARE SQL_STATEMENT NVARCHAR(8000);
drop table if exists tmp_valuesss;
SET @SQL_STATEMENT = CONCAT('CREATE TABLE IF NOT EXISTS tmp_valuesss AS (SELECT * FROM ', table_name, ')');
PREPARE STMT FROM @SQL_STATEMENT;
EXECUTE STMT;
DEALLOCATE PREPARE STMT; -- Drew added -------------------
alter table tmp_valuesss add the_field float;
begin
declare my_key_id int(11); /*variable that will be assigned from the value in cursor*/
DECLARE done INT DEFAULT FALSE; /*for cursor break*/
DECLARE cr_cursor cursor for select key_id from tmp_valuesss; /*cursor declaration*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /*break thingy*/
open cr_cursor;
read_loop: LOOP
FETCH cr_cursor INTO my_key_id;
IF done THEN
LEAVE read_loop;
END IF;
select my_key_id;
END LOOP;
close cr_cursor;
end;
END $$
DELIMITER ;
有几点需要注意。首先,上面显示整个块的原因是为了帮助这里的未来访问者,他们可能因为 DELIMITER 问题而在创建存储过程时遇到问题。此外,开头的下降对于第二次及以后编辑过程很重要。
此外,这显然只是对您提出的概念存储过程的测试。意思是,通过在 LOOP 中执行 select my_key_id;
,您实际上在消费者端创建了一个额外的结果集(使用调用语句调用存储过程的结果集)。您是否具备处理代码中返回的多个结果集的能力将影响您对此的审查。
此外,它由您作为参数传递的 table 名称的状态驱动。因此,如果该 table 包含值或空值,您将根据您的代码和您决定传递该 table 名称来获得您所获得的结果。一个据称包含列 key_id
的 table,因为这是您开始编写存储过程的方式。
下面的视图显示它正在运行,有多个结果集。
上图显示了一个 table,其中有 2 行用于鱼和青蛙。返回了两个结果集(这就是您对其进行编码的方式)。我突出显示了第二个结果集,它显示了从它返回的值(它是 id 2)...循环完成之前发生的最后一行。
与其尝试第三次编辑此答案,我建议您在 link 我在您的问题下发表的评论中加入我的聊天。
问题很明显,但我尝试了很多方法来修复它,包括使用与 table 字段不同的变量名称。从游标中获取的值总是 returns null。分配给游标提取的值是相同的数据类型 (int(11))。我正在做的是将从光标的 select table 中获取的 key_id 值分配给 @my_key_id int(11) 变量,但它一直为 null。
declare my_key_id int(11); /*variable that will be assigned from the value in cursor*/
DECLARE done INT DEFAULT FALSE; /*for cursor break*/
DECLARE cr_cursor cursor for select key_id from tmp_valuesss; /*cursor declaration*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /*break thingy*/
open cr_cursor;
read_loop: LOOP
IF done THEN
LEAVE read_loop;
END IF;
select @my_key_id;
FETCH cr_cursor INTO my_key_id;
END LOOP;
close cr_cursor;
您将用户变量(带有 @
符号的变量)误认为是局部变量(带有 DECLARE 的变量)。
您的用户变量从未设置,因此始终为空。
此外,取消分配任何准备变量。
Fetch
已上移以出现在 LOOP 的开头。
drop procedure if exists calculate_thingy;
delimiter $$
CREATE PROCEDURE calculate_thingy
(
IN table_name VARCHAR(100)
)
BEGIN
DECLARE SQL_STATEMENT NVARCHAR(8000);
drop table if exists tmp_valuesss;
SET @SQL_STATEMENT = CONCAT('CREATE TABLE IF NOT EXISTS tmp_valuesss AS (SELECT * FROM ', table_name, ')');
PREPARE STMT FROM @SQL_STATEMENT;
EXECUTE STMT;
DEALLOCATE PREPARE STMT; -- Drew added -------------------
alter table tmp_valuesss add the_field float;
begin
declare my_key_id int(11); /*variable that will be assigned from the value in cursor*/
DECLARE done INT DEFAULT FALSE; /*for cursor break*/
DECLARE cr_cursor cursor for select key_id from tmp_valuesss; /*cursor declaration*/
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; /*break thingy*/
open cr_cursor;
read_loop: LOOP
FETCH cr_cursor INTO my_key_id;
IF done THEN
LEAVE read_loop;
END IF;
select my_key_id;
END LOOP;
close cr_cursor;
end;
END $$
DELIMITER ;
有几点需要注意。首先,上面显示整个块的原因是为了帮助这里的未来访问者,他们可能因为 DELIMITER 问题而在创建存储过程时遇到问题。此外,开头的下降对于第二次及以后编辑过程很重要。
此外,这显然只是对您提出的概念存储过程的测试。意思是,通过在 LOOP 中执行 select my_key_id;
,您实际上在消费者端创建了一个额外的结果集(使用调用语句调用存储过程的结果集)。您是否具备处理代码中返回的多个结果集的能力将影响您对此的审查。
此外,它由您作为参数传递的 table 名称的状态驱动。因此,如果该 table 包含值或空值,您将根据您的代码和您决定传递该 table 名称来获得您所获得的结果。一个据称包含列 key_id
的 table,因为这是您开始编写存储过程的方式。
下面的视图显示它正在运行,有多个结果集。
上图显示了一个 table,其中有 2 行用于鱼和青蛙。返回了两个结果集(这就是您对其进行编码的方式)。我突出显示了第二个结果集,它显示了从它返回的值(它是 id 2)...循环完成之前发生的最后一行。
与其尝试第三次编辑此答案,我建议您在 link 我在您的问题下发表的评论中加入我的聊天。