1

次のMYSQLストアドプロシージャがあります。

CREATE PROCEDURE DWH.product_stats(OUT int_return INT)
BEGIN
  DECLARE vc_sku, 
      vc_prod_id    VARCHAR(100);

  DECLARE int_views,
      int_fav,
      int_month, 
      int_year, 
      not_found     INT DEFAULT 0;

 DECLARE cur_sku CURSOR FOR

 SELECT product_id, sku FROM product LIMIT 0,10;

 DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1;

 OPEN cur_sku;
 REPEAT

FETCH cur_sku INTO vc_prod_id, vc_sku;
IF NOT not_found THEN
  -- Number of Views and Favs
  SELECT  COUNT(CASE WHEN event_type_id = 1 THEN 1 END) AS views,
          COUNT(CASE WHEN event_type_id = 5 THEN 1 END) AS favs,
          MONTH(logged_at) AS log_mon, 
          YEAR(logged_at) AS log_year INTO int_views, int_fav, int_month, int_year
  FROM report_event
  WHERE object_id = vc_prod_id
  GROUP BY log_mon, log_year
  ORDER BY log_year, log_mon; 

  -- DEBUG
  SELECT vc_sku, vc_prod_id, int_views, int_fav, int_month, int_year ;
END IF;
UNTIL not_found END REPEAT ;
CLOSE cur_sku;

END;

これを正常に実行すると、エラーはありません。私は結果を得る。しかし、MYSQL ストアド プロシージャでこれを使用します。次に、ストア プロシージャを実行しようとすると、「結果は複数の行で構成されています」というエラーが表示されます。これは、月と年の GROUP BY があり、製品に対して複数のレコードが生成されるためです。しかし、それは私が欲しい機能です。この問題に対処する最善の方法は何でしょうか?

4

1 に答える 1

0

2番目のSQLは複数の行を返すため、その結果で何かを行うには、それをカーソルとしてまとめて持つ必要があるため、私が取ったアプローチは完全に間違っていると思います。そのため、SPを次のように書き直しましたが、現在は正常に動作しています。

DROP PROCEDURE IF EXISTS DWH.product_stats;
CREATE PROCEDURE DWH.product_stats(OUT int_return INT)
BEGIN
DECLARE vc_sku, 
      vc_prod_id    VARCHAR(100);

DECLARE not_found INT DEFAULT 0;

DECLARE cur_sku CURSOR FOR
  SELECT product_id, sku FROM product LIMIT 0,10;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found = 1;

OPEN cur_sku;
REPEAT
  FETCH cur_sku INTO vc_prod_id, vc_sku;
  IF NOT not_found THEN
  SET @vc_prod_id = vc_prod_id;
  -- Number of Views and Favs
  BEGIN
    DECLARE int_views,
            int_fav,
            int_month, 
            int_year INT;

    DECLARE not_found_ev INT DEFAULT 0;

    DECLARE cur_event CURSOR FOR
      SELECT  
        COUNT(CASE WHEN event_type_id = 1 THEN 1 END) AS views,
        COUNT(CASE WHEN event_type_id = 5 THEN 1 END) AS favs,
        MONTH(logged_at) AS log_mon, 
        YEAR(logged_at) AS log_year 
        FROM report_event
        WHERE object_id = @vc_prod_id
        GROUP BY log_mon, log_year
        ORDER BY log_year, log_mon;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found_ev = 1;  

      OPEN cur_event;

      report_event_loop : LOOP 

        FETCH cur_event INTO int_views, int_fav, int_month, int_year; 
        IF not_found_ev THEN
          CLOSE cur_event;
          LEAVE report_event_loop;
        END IF;
        -- DEBUG
        SELECT @vc_prod_id, vc_sku, vc_prod_id, int_views, int_fav, int_month, int_year ;
      END LOOP;
      SET not_found_ev = 0;
  END;
 END IF;
 UNTIL not_found END REPEAT ;
 CLOSE cur_sku;
END;
于 2013-02-05T06:02:13.303 に答える