mySQL(存储过程)游标在最后一行无限循环

时间:2013-01-10 23:35:27

标签: mysql sql stored-procedures

我有以下代码:问题是在creature_y循环的最后一行没有结束并且无限地插入相同的值(增加的guid)。 我尝试了几种改变继续处理程序的方法,但似乎不是这样。

DELIMITER $$
DROP PROCEDURE IF EXISTS creature_copy
$$
CREATE PROCEDURE creature_copy ()
BEGIN

    DECLARE done INT DEFAULT 0;
    DECLARE new_guid INT(10);

    -- Creature definition
    DECLARE y_guid INT(10);
    DECLARE y_id mediumint(8);
    DECLARE y_map int(5);
    DECLARE y_modelid mediumint(8);
    DECLARE y_position_x float(10);
    DECLARE y_position_y float(10);
    DECLARE y_position_z float(10);
    DECLARE y_orientation float(10);
    DECLARE y_spawntimesecs INT(10);
    DECLARE y_curhealth INT(10);
    DECLARE y_curmana INT(10);
    DECLARE y_MovementType tinyint(3);

    -- waypoints definition
    DECLARE w_id INT(10);
    DECLARE w_point mediumint(8);
    DECLARE w_position_x float(10);
    DECLARE w_position_y float(10);
    DECLARE w_position_z float(10);
    DECLARE w_orientation float(10);

    -- Generate creatures map
    DECLARE creature_sel CURSOR FOR
      SELECT guid,id, map, modelid, position_x, position_y, position_z, orientation, spawntimesecs, curhealth, curmana, MovementType
        FROM creature_y;

    -- Generate waypoints map
    DECLARE waypoint_sel CURSOR FOR
                SELECT id, point, position_x, position_y, position_z, orientation
                    FROM creature_movement 
                        WHERE creature_movement.id = y_guid;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN creature_sel;
-- Cleanup tables before re-running
TRUNCATE creature_t;
TRUNCATE waypoint_data;

-- Set starting guid before loop
SET new_guid = 504115;

creature_loop:LOOP

        if done = 1 THEN 
            -- set done = 0;
            CLOSE creature_sel;
            LEAVE creature_loop;
        end if;

        SET new_guid = new_guid + 1;

    FETCH creature_sel INTO y_guid, y_id, y_map, y_modelid, y_position_x, y_position_y, y_position_z, y_orientation, y_spawntimesecs, y_curhealth, y_curmana, y_MovementType;
    INSERT INTO creature_t(guid, id, map, modelid, position_x, position_y, position_z, orientation, spawntimesecs, curhealth, curmana, MovementType) VALUES(new_guid, y_id, y_map, y_modelid, y_position_x, y_position_y, y_position_z, y_orientation, y_spawntimesecs, y_curhealth, y_curmana, y_MovementType);

        OPEN waypoint_sel;
        waypoint_loop:LOOP
                FETCH waypoint_sel INTO w_id, w_point, w_position_x, w_position_y, w_position_z, w_orientation;

                IF done = 1 THEN 
                     SET done = 0;
                    LEAVE waypoint_loop ;
                END IF;

                INSERT INTO waypoint_data(id, point, position_x, position_y, position_z, orientation) VALUES (new_guid, w_point, w_position_x, w_position_y, w_position_z, w_orientation);
        END LOOP waypoint_loop;
        CLOSE waypoint_sel;

END LOOP creature_loop;
CLOSE creature_sel;
END;

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。 要使用2个不同的继续处理程序(查看光标是否在末尾),您需要将代码拆分为块

BLOCK1: BEGIN

    DECLARE done INT DEFAULT 0;
    -- First cursor
    DECLARE sel CURSOR FOR
      SELECT column
        FROM table;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN sel;

    sel_loop:LOOP
        if done = 1 THEN 
            set done = 0;
            CLOSE sel;
            LEAVE sel_loop;
        end if;

        FETCH sel INTO variable1;
        -- Do something in loop
        -- Start second code-block      
        BLOCK2: BEGIN
        DECLARE done2 INT DEFAULT 0;

        -- define second cursor
        DECLARE sel2 CURSOR FOR
            SELECT column
            FROM table
                WHERE column = condition;
            -- define second handler
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done2 = 1;
            -- now you can make second cursor loop and it will finish properly.
        OPEN sel2;
        sel2_loop:LOOP
                FETCH sel2 INTO variable2;

                IF done2 = 1 THEN 
                     SET done2 = 0;
                    LEAVE sel2_loop ;
                END IF;

        -- do something in second loop
        END LOOP waypoint_loop;
        CLOSE waypoint_sel;

-- End your code blocks and close first loop / cursor
END BLOCK2;

END LOOP sel_loop;
CLOSE sel;
END BLOCK1