为什么mysql不允许在游标中获取用户定义的变量?

时间:2014-11-21 02:04:45

标签: mysql

我有这样的代码,mysql发布错误:

行:FETCH cur_recycle_batch INTO @id, @created_by, @created_date;发布错误。

有谁知道为什么mysql不允许获取用户定义的变量?

CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_row`()
BEGIN

    DECLARE done TINYINT DEFAULT FALSE;
    DECLARE cur_recycle_batch CURSOR FOR SELECT 
                                                id, created_by, created_date
                                            FROM
                                                outsourcing_recycle_batch
                                            order by created_date;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    START transaction;

        OPEN cur_recycle_batch;

            insert_loop : loop

                FETCH cur_recycle_batch INTO @id, @created_by, @created_date;

                IF done THEN

                    LEAVE insert_loop;
                END IF;

                INSERT INTO `test_db`.`outsourcing_recycle_batch_history_list`
                (`outsourcing_recycle_batch_pk`,
                `outsourcing_history_pk`,
                `created_by`,
                `created_by_full_name`,
                `created_date`)
                VALUES
                (@id,
                1,
                @created_by,
                'AAAAAAAA',
                @created_date);


            END LOOP;

        CLOSE cur_recycle_batch;

    commit;

END

1 个答案:

答案 0 :(得分:0)

有一种解决方法:n局部变量而不是依赖用户变量。

DECLARE

鉴于此变通方法,实现FETCH INTO用户变量绝不是优先事项。

有一个更简单的解决方法,以您的示例为例:根本不用光标,只需使用INSERT...SELECT插入一组行即可。

CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_row`()
BEGIN
    DECLARE local_id INT;
    DECLARE local_created_by VARCHAR(20);
    DECLARE local_created_date DATE;
    DECLARE done TINYINT DEFAULT FALSE;
    DECLARE cur_recycle_batch CURSOR FOR SELECT id, created_by, created_date
                                            FROM outsourcing_recycle_batch
                                            ORDER BY created_date;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    START transaction;
        OPEN cur_recycle_batch;
            insert_loop : loop
                FETCH cur_recycle_batch INTO local_id, local_created_by, local_created_date;
                IF done THEN
                    LEAVE insert_loop;
                END IF;
                INSERT INTO `test_db`.`outsourcing_recycle_batch_history_list`
                (`outsourcing_recycle_batch_pk`,
                `outsourcing_history_pk`,
                `created_by`,
                `created_by_full_name`,
                `created_date`)
                VALUES
                (local_id,
                1,
                local_created_by,
                'AAAAAAAA',
                local_created_date);
            END LOOP;
        CLOSE cur_recycle_batch;
    commit;
END

我不知道您是否简化了示例。您可能需要使用游标对值进行其他逐行操作,而不是简单地插入。