2011-11-14 22 views
1

私はランクのあるビューから一時テーブルに行を挿入するストアドプロシージャを持っています。一時テーブルがMySQLストアドプロシージャの結果セットを返しません

一時テーブルは、値を挿入したカーソルループを実行する前に作成され、ループが完了した後にSELECTされます。

ただし、私が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 ; 

ここEDIT

はcohortMessagesPerMemberPerWeekがあなたのcurカーソルのnot found handlerが欠けているように見えます

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

のように見えるものです。これは、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に設定されます。できるだけ説明できるので、私の答えに投稿したリンクを素早く読んでください!それが助けてくれてうれしい。 –

関連する問題