MySQL存储过程:如何声明游标以从临时表中选择?

5

在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 ;

为什么不使用在创建临时表时使用的select语句来创建游标呢?创建临时表会产生大量IO。在这种情况下,临时表的附加值是什么?它只有3个字段,不太可能被更新。请提供更多关于所需内容的详细信息。 - Cedric Simon
感谢您的建议,Cedric。 - Touka
问题在于我想多次使用临时表,但我不想多次执行选择操作! - Touka
3
我明白了,我使用了嵌套的BEGIN..END块,就像这里所述。 - Touka
2个回答

5
在您的示例中,请在创建临时表之前声明光标。看起来不合逻辑,但它能实现预期效果。

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 之后,你需要完成声明部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接