MySQL存储过程:如何为临时表中的Select声明一个Cursor?

时间:2013-10-03 14:04:18

标签: mysql sql stored-procedures

在MySQL存储过程中,如何为从select语句创建的临时表声明游标。 谢谢,

DELIMITER $$
DROP PROCEDURE IF EXISTS `sp_foo`$$
CREATE PROCEDURE sp_foo()
BEGIN   
    DROP TEMPORARY TABLE IF EXISTS `TmpMyTable`;
    CREATE TEMPORARY TABLE `TmpMyTable` (
        `id`            INT(11) NOT NULL AUTO_INCREMENT,
        `person_id`     INT(11) NOT NULL,
        `first_name`    VARCHAR(60) NOT NULL,
        `last_name`     VARCHAR(60) NOT NULL,
        PRIMARY KEY  (`id`),
        INDEX `idx_first_name` (`person_id`),
        INDEX `idx_first_name` (`first_name`)
    ) ENGINE=MYISAM         
        SELECT 
            id AS `person_id`,
            first_name,
            last_name
        FROM person
    ;

    DECLARE _person_id INT(11); 
    DECLARE personCursor CURSOR 
    FOR 
        SELECT * FROM TmpMyTable;       

    OPEN personCursor;
    LOOP
        FETCH personCursor INTO _person_id;

        ...

    END LOOP;   
    END$$
DELIMITER ;

2 个答案:

答案 0 :(得分:2)

在您的示例中,在创建临时表之前进行游标声明。似乎不合逻辑,但它确实有效。

答案 1 :(得分:0)

您可以创建两个单独的过程。 像这样:

DELIMITER $$
DROP PROCEDURE IF EXISTS `tmp_tbl`$$
CREATE PROCEDURE tmp_tbl()
BEGIN   
    DROP TEMPORARY TABLE IF EXISTS `TmpMyTable`;
    CREATE TEMPORARY TABLE `TmpMyTable` (
        `id`            INT(11) NOT NULL AUTO_INCREMENT,
        `person_id`     INT(11) NOT NULL,
        `first_name`    VARCHAR(60) NOT NULL,
        `last_name`     VARCHAR(60) NOT NULL,
        PRIMARY KEY  (`id`),
        INDEX `idx_first_name` (`person_id`),
        INDEX `idx_first_name` (`first_name`)
    ) ENGINE=MYISAM         
        SELECT 
            id AS `person_id`,
            first_name,
            last_name
        FROM person
    ;   
    END$$
DELIMITER ;
DELIMITER $$
DROP PROCEDURE IF EXISTS `sp_foo`$$
CREATE PROCEDURE sp_foo()
BEGIN   
    DECLARE _person_id INT(11); 
    DECLARE personCursor CURSOR 
    FOR 
        SELECT * FROM TmpMyTable;       

    OPEN personCursor;
    LOOP
        FETCH personCursor INTO _person_id;

        ...

    END LOOP;   
    END$$
DELIMITER ;

然后您可以依次调用它们。

call tmp_tbl();
call sp_foo();

实际上,在您BEGIN PROCEDURE之后,您需要完成声明部分。