views:

10

answers:

1

I have the following bunch of code trying to update a field using 2 cursors the one inside the other. I use the first cursor just to get an id value (1st cursor) and then I get a list of other id values based on that id (2nd cursor). The problem is that the result set from the 2nd cursor contains the last id twice! I can't find the bug! Something in the loop, something in the termination variable for the 2 cursors?

Any help more than welcome! Thanks in advance!

DELIMITER $$ DROP PROCEDURE IF EXISTS updateNumberOfPoisForPlacesWithChildren$$ CREATE PROCEDURE updateNumberOfPoisForPlacesWithChildren() BEGIN DECLARE single_place_id INT(11); DECLARE single_unique_parents_id INT(11); DECLARE done, temp_number_of_pois, sum_number_of_pois INT DEFAULT 0;

    DECLARE unique_parents_ids CURSOR FOR SELECT DISTINCT `parent_id` FROM `places` WHERE `parent_id` IS NOT NULL;
    DECLARE temp_places_ids CURSOR FOR SELECT `id` FROM `places` WHERE `parent_id` = single_unique_parents_id;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN unique_parents_ids;

    main_loop_for_parent_ids : LOOP
        SET sum_number_of_pois = 0;
        IF done = 1 THEN
            CLOSE unique_parents_ids;
            LEAVE main_loop_for_parent_ids;
        END IF;

        IF NOT done = 1 THEN
            FETCH unique_parents_ids INTO single_unique_parents_id;
            OPEN temp_places_ids;
            main_loop_for_places : LOOP
                IF done = 1 THEN
                    CLOSE temp_places_ids;
                    LEAVE main_loop_for_places;
                END IF;

                IF NOT done = 1 THEN
                    FETCH temp_places_ids INTO single_place_id;
                    SELECT COUNT(`id`) INTO temp_number_of_pois FROM `pois` WHERE `place_id` = single_place_id;
                    SET sum_number_of_pois = sum_number_of_pois + temp_number_of_pois;
                END IF;

            END LOOP;   

            UPDATE `places` SET `number_of_pois`=sum_number_of_pois WHERE `id` = single_unique_parents_id;

        END IF;
    END LOOP;



END$$

DELIMITER ;

A: 

I think your problem is about here...

        IF NOT done = 1 THEN
            FETCH temp_places_ids INTO single_place_id;
            SELECT COUNT(`id`) INTO temp_number_of_pois FROM `pois` WHERE `place_id` = single_place_id;
            SET sum_number_of_pois = sum_number_of_pois + temp_number_of_pois;
        END IF;

The FETCH sets DONE to be 1 when it exhausts the result set, but you proceed because you've already passed the DONE test.

Perhaps...

 FETCH temp_places_ids INTO single_place_id;
 IF NOT done = 1 THEN
     SELECT COUNT(`id`) INTO temp_number_of_pois FROM `pois` WHERE `place_id` = single_place_id;
     SET sum_number_of_pois = sum_number_of_pois + temp_number_of_pois;
 END IF;
Brian Hooper
It works! Thank you
chzigkol