问题很明显,但我已经尝试了很多东西来修复它,包括使用不同的变量名而不是表字段。从游标获取的值始终返回null。分配给游标提取的值是相同的数据类型(int(11))。我正在做的是将游标的select_id值从游标的select表中分配到@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;
答案 0 :(得分:4)
您误将用户变量(带有@
符号的用户变量)与局部变量(带有DECLARE的用户变量)混淆。
您的用户变量从未设置过,因此始终为空。
此外,DEALLOCATE任何PREPARE var。
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问题,因此创建存储过程可能会遇到问题。此外,开头的下降对于第二次及之后对proc的编辑很重要。
此外,这显然只是测试您提供的概念存储过程。这意味着,通过在LOOP中执行select my_key_id;
,您实际上在消费者端创建了一个额外的结果集(使用call语句调用存储过程)。您是否有能力处理代码中的多个结果集将影响您对此的审核。
此外,它由您作为参数传递的表名的状态驱动。因此,如果该表包含值或空值,则可以根据代码和传递该表名的决定获得所获得的值。据称包含列key_id
的表,因为这是您开始编写存储过程的方式。
下面的视图是有效的,有多个结果集。
上面的图片显示了一张桌子,里面有两排鱼和青蛙。返回了两个结果集(这就是你编码的方式)。我突出显示了第二个结果集,它显示了从它返回的值(它是id 2)...在LOOP结束之前发生的最后一行。
我建议您第三次尝试编辑此答案,而不是尝试在我的问题中根据我在评论中提供的链接与我聊天。