MySQL Cursor只获取一行

时间:2012-08-18 10:38:46

标签: 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;

当我调用此过程时,MySQL只获取一行(_debug rows增加1)。为什么??这是一个错误吗?

3 个答案:

答案 0 :(得分: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

答案是,如果游标没有返回任何行,而且如果表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;

           [...]

补充:显然可以在没有第二个变量的情况下通过简单地重置选择后的“完成”:

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

           [...]

           select id into newValue from B where ...

           SET done = FALSE;

           [...]

答案 1 :(得分:0)

您是否尝试过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;

答案 2 :(得分:0)

IF done THEN
         LEAVE main_loop;
ELSE
         ITERATE main_loop;
END IF;