2011-11-14 78 views
1

我有一个存储过程,它将视图中的行插入到临时表中。临时表在MySQL存储过程中不返回结果集

临时表是在我运行插入值的游标循环之前创建的,并且在循环完成后进行SELECT'ed。

但是,当我CALL medianMessagesPerWeek();我得到一个“错误代码:1329没有数据 - 获取,选择或处理零行。”

如果我创建表的MyISAM表,我可以手动选择表并确认数据已经被插入,但存储的过程还是会给予我什么。

我在这里错过了什么吗?

DELIMITER $$ 

USE `yongopal_metrics`$$ 

DROP PROCEDURE IF EXISTS `medianMessagesPerWeek`$$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `medianMessagesPerWeek`() 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE tempJoinWeek, tempActiveWeek, rank INT DEFAULT 0; 
    DECLARE joinWeek, activeWeek, memberNo, messages INT; 
    DECLARE cur CURSOR FOR SELECT * FROM cohortMessagesPerMemberPerWeek; 

    DROP TEMPORARY TABLE IF EXISTS medianMessagesPerWeek; 
    CREATE TEMPORARY TABLE medianMessagesPerWeek 
    (
     joinWeek INT, 
     activeWeek INT, 
     memberNo INT, 
     messages INT, 
     rank INT 
    ) ENGINE=MEMORY;  

    OPEN cur; 

    read_loop: LOOP 
     FETCH cur INTO joinWeek, activeWeek, memberNo, messages; 
     IF done THEN 
      LEAVE read_loop; 
     END IF; 

     IF tempJoinWeek = joinWeek AND tempActiveWeek = activeWeek THEN 
      SET rank = rank + 1; 
     ELSE 
      SET tempJoinWeek = joinWeek; 
      SET tempActiveWeek = activeWeek; 
      SET rank = 1; 
     END IF; 
     INSERT INTO medianMessagesPerWeek VALUES (joinWeek, activeWeek, memberNo, messages, rank); 
    END LOOP; 

    CLOSE cur; 

    SELECT * FROM medianMessagesPerWeek; 
    DROP TEMPORARY TABLE IF EXISTS medianMessagesPerWeek; 
    END$$ 

DELIMITER ; 

编辑

这里是cohortMessagesPerMemberPerWeek样子

DELIMITER $$ 

USE `yongopal_metrics`$$ 

DROP VIEW IF EXISTS `cohortMessagesPerMemberPerWeek`$$ 

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `cohortMessagesPerMemberPerWeek` AS 
SELECT 
    WEEK(`m`.`regDatetime`,0) AS `joinWeek`, 
    WEEK(`cd`.`sendDate`,0) AS `activeWeek`, 
    `m`.`memberNo` AS `memberNo`, 
    COUNT(0)  AS `messages` 
FROM (`yongopal`.`chatData` `cd` 
    JOIN `yongopal`.`members` `m` 
    ON ((`cd`.`sender` = `m`.`memberNo`))) 
GROUP BY WEEK(`m`.`regDatetime`,0),WEEK(`cd`.`sendDate`,0),`m`.`memberNo` 
ORDER BY WEEK(`m`.`regDatetime`,0),WEEK(`cd`.`sendDate`,0)$$ 

DELIMITER ; 

回答

2

你好像缺少一个not found handlercur光标。当fetch语句不再返回任何行(因此您已达到游标声明返回的数据集的末尾)时,将done布尔值设置为true是必要的。

试试这个:

DELIMITER $$ 

USE `yongopal_metrics`$$ 

DROP PROCEDURE IF EXISTS `medianMessagesPerWeek`$$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `medianMessagesPerWeek`() 
BEGIN 
    DECLARE done INT DEFAULT FALSE; 
    DECLARE tempJoinWeek, tempActiveWeek, rank INT DEFAULT 0; 
    DECLARE joinWeek, activeWeek, memberNo, messages INT; 
    DECLARE cur CURSOR FOR SELECT * FROM cohortMessagesPerMemberPerWeek; 

    declare continue handler for not found set done := true; 

    DROP TEMPORARY TABLE IF EXISTS medianMessagesPerWeek; 
    CREATE TEMPORARY TABLE medianMessagesPerWeek 
    (
     joinWeek INT, 
     activeWeek INT, 
     memberNo INT, 
     messages INT, 
     rank INT 
    ) ENGINE=MEMORY;  

    OPEN cur; 

    read_loop: LOOP 
     FETCH cur INTO joinWeek, activeWeek, memberNo, messages; 
     IF done THEN 
      LEAVE read_loop; 
     END IF; 

     IF tempJoinWeek = joinWeek AND tempActiveWeek = activeWeek THEN 
      SET rank = rank + 1; 
     ELSE 
      SET tempJoinWeek = joinWeek; 
      SET tempActiveWeek = activeWeek; 
      SET rank = 1; 
     END IF; 
     INSERT INTO medianMessagesPerWeek VALUES (joinWeek, activeWeek, memberNo, messages, rank); 
    END LOOP; 

    CLOSE cur; 

    SELECT * FROM medianMessagesPerWeek; 
    DROP TEMPORARY TABLE IF EXISTS medianMessagesPerWeek; 
    END$$ 

DELIMITER ; 
+0

哇,那没有的伎俩!什么确切声明“找不到”呢? –

+0

我猜如果没有声明,存储的过程会在光标结束循环后结束? –

+1

是的。有点。如果你错过了'找不到'处理程序,那么proc会将'找不到数据'状态(即,没有数据留在从光标读取的状态)作为错误处理。添加处理程序告诉proc“如果你得到'找不到数据'状态不要抛出错误 - 只需将我的'done'布尔值设置为true”。快速阅读我在答复中发布的链接,因为它能够比我更好地解释它!很高兴帮助。 –

相关问题