Pet*_*ter 8 mysql sql database cursor
我的SQL:
CREATE PROCEDURE INV_MIN_PURCHASE_PRICE()
BEGIN
DECLARE done INT;
DECLARE current_inventory_ID INT;
DECLARE cur1 CURSOR FOR SELECT inventory_ID FROM _inventory;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET done = 0;
OPEN cur1;
REPEAT
FETCH cur1 INTO current_inventory_ID;
UPDATE _debug SET rows=rows+1;
UNTIL done
END REPEAT;
CLOSE cur1;
END;
Run Code Online (Sandbox Code Playgroud)
当我调用此过程时,MySQL只获取一行(_debug rows增加1).为什么??这是一个错误吗?
use*_*933 13
我在MySQL中遇到了与存储过程相同的问题.它应该从表中获取某个列中具有空值的所有记录,然后从另一个表中填充该值.然而,它在一条记录后停止:
CREATE PROCEDURE `updateRecord`()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE recordId, newValue INT;
DECLARE current_record CURSOR FOR SELECT id FROM A where b_id is null;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN current_record;
main_loop: LOOP
FETCH current_record INTO recordId;
IF done THEN
LEAVE main_loop;
END IF;
-- fetching some value from table b
select id into newValue from B where ...
-- setting new value in record
update A set b_id = newValue where id = recordId;
END LOOP;
END
Run Code Online (Sandbox Code Playgroud)
答案是,如果游标没有返回任何行,而且如果表B上的select没有返回任何行,则不仅执行"找不到处理程序".我的解决方案是使用由处理程序设置的第二个变量,并在select之后重置"done"变量:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE, noBfound = TRUE;
[...]
select id into newValue from B where ...
IF (noBfound = TRUE) THEN
SET done = FALSE;
END IF;
[...]
Run Code Online (Sandbox Code Playgroud)
另外:通过简单地重置选择后的"完成",显然可以不使用第二个变量:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
[...]
select id into newValue from B where ...
SET done = FALSE;
[...]
Run Code Online (Sandbox Code Playgroud)
您是否尝试过使用 LOOP 而不是 REPEAT 结构?似乎在 MySQL 中工作得更好。将 REPEAT 到 END REPEAT 部分替换为:
inv_loop: LOOP
FETCH cur1 INTO current_inventory_ID;
IF done = 1 THEN
LEAVE inv_loop;
END IF;
UPDATE _debug SET rows=rows+1;
END LOOP;
Run Code Online (Sandbox Code Playgroud)