6

我想创建一个能够执行多任务的存储过程。然后它在下面收到错误消息

Error Code: 1338 Cursor declaration after handler declaration

请看我的店铺流程

CREATE PROCEDURE `spTest`(OUT v1 VARCHAR(500), OUT v2 VARCHAR(500))
BEGIN

    DECLARE  _cur_1 CURSOR FOR
        SELECT id
        FROM tbl_1;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _cur1Done = 1;

    DECLARE  _cur_2 CURSOR FOR
        SELECT id
        FROM tbl_2;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _cur2Done = 1;

    .......
4

2 回答 2

6

一个块中可能只有一个continue handler处于活动状态。Multiplecontinue handler得到Duplicate handler declared in same block问题,即使你得到正确的声明顺序(首先是所有游标,然后是处理程序)。

您可以通过创建一个专门用于游标访问的块来解决此问题。您可以将这些代码块放在同一个父块中,或者放在嵌套循环中,或者任何地方。

DELIMITER $$
CREATE PROCEDURE `spTest`(OUT v1 VARCHAR(500), OUT v2 VARCHAR(500))
BEGIN

    declare tbl_1_id int;
    declare tbl_2_id int;

    declare _cur1Done boolean default false;
    declare _cur2Done boolean default false;

    DECLARE  _cur_1 CURSOR FOR SELECT id FROM tbl_1;
    DECLARE  _cur_2 CURSOR FOR SELECT id FROM tbl_2;

    begin -- dedicated block to fetch from cursor 1 and update its flag
        declare continue handler for not found set _cur1Done = TRUE;
        fetch _cur_1 into tbl_1_id;
    end;

    begin -- dedicated block to fetch from cursor 2 and update its flag
        declare continue handler for not found set _cur2Done = TRUE;
        fetch _cur_2 into tbl_2_id;
    end;
END $$
DELIMITER ;
于 2015-10-29T16:12:14.543 回答
3

手册中它说

游标声明必须出现在处理程序声明之前以及变量和条件声明之后。

你也不能有多个 continue 处理程序(MySQL 应该如何知道哪个 continue 处理程序与哪个游标相关?不幸的是你不能指定),除非你嵌套它们,例如像这样:

DELIMITER $$
CREATE PROCEDURE `spTest`(OUT v1 VARCHAR(500), OUT v2 VARCHAR(500))
BEGIN
BLOCK1:BEGIN

    DECLARE variable1 INT;

    DECLARE  _cur_1 CURSOR FOR SELECT id FROM tbl_1;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _cur1Done = 1;
    LOOP1: LOOP
    FETCH _cur_1 INTO variable1;
    IF _cur1Done THEN 
        CLOSE _cur_1;
        LEAVE LOOP1;
    END IF;

    BLOCK2:BEGIN

        DECLARE variable2 INT;

        DECLARE  _cur_2 CURSOR FOR SELECT id FROM tbl_2;

        DECLARE CONTINUE HANDLER FOR NOT FOUND SET _cur2Done = 1;

        OPEN _cur_2;
        LOOP2: LOOP

            FETCH _cur_2 INTO variable2;
            IF _cur2Done THEN
                CLOSE _cur_2;
                LEAVE LOOP2;
            END IF;
        END LOOP LOOP2;
    END BLOCK2;
END LOOP LOOP1;
END BLOCK1;
END $$
DELIMITER ;
于 2012-07-05T08:34:47.833 回答