2012-02-27 10 views
2

MySQLストアドプロシージャの新機能。 4つのSELECT行(以下)のいずれかをコメント解除すると、ルーチンはFETCHループから抜け出します。なぜカーソル内のテーブルからのSELECTステートメントカーソルをEXITへ強制的に移動

-- -------------------------------------------------------------------------------- 
-- Routine DDL 
-- Note: comments before and after the routine body will not be stored by the server 
-- -------------------------------------------------------------------------------- 
DELIMITER $$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `UpdateStatusAudit`() 
BEGIN 
    -- Create loop for all $Service records 
    DECLARE svc_id INT; 
    DECLARE test INT; 
    DECLARE svc_name VARCHAR(100); 
    DECLARE no_more_rows BOOLEAN; 
    DECLARE up_duration DECIMAL(11,2); 
    DECLARE down_duration DECIMAL(11,2); 
    DECLARE maint_duration DECIMAL(11,2); 
    DECLARE degr_duration DECIMAL(11,2); 
    DECLARE services_cur CURSOR FOR SELECT service_id,service_name FROM services ORDER BY service_id; 

    -- Declare 'handlers' for exceptions 
    DECLARE CONTINUE HANDLER FOR NOT FOUND 
    SET no_more_rows = TRUE; 

    OPEN services_cur; 
    the_loop: LOOP 
    FETCH services_cur INTO svc_id,svc_name; 
    IF no_more_rows THEN 
     CLOSE services_cur; 
     LEAVE the_loop; 
    END IF; 
    SET up_duration = 0; 
    SET down_duration = 0; 
    SET maint_duration = 0; 
    SET degr_duration = 0; 
    SELECT svc_id; 
    BEGIN 
     -- SELECT IFNULL(sum(duration),0) INTO up_duration FROM daily_audit_summary where service_id = svc_id AND status = 'UP' AND Date = current_date - 1 group by date,service_id,status; 
     -- SELECT IFNULL(sum(duration),0) INTO down_duration FROM daily_audit_summary where service_id = svc_id AND status = 'DOWN' AND Date = current_date - 1 group by date,service_id,status; 
     -- SELECT IFNULL(sum(duration),0) INTO maint_duration FROM daily_audit_summary where service_id = svc_id AND status = 'MAINT' AND Date = current_date - 1 group by date,service_id,status; 
     -- SELECT IFNULL(sum(duration),0) INTO degr_duration FROM daily_audit_summary where service_id = svc_id AND status = 'DEGR' AND Date = current_date - 1 group by date,service_id,status; 
    END; 
    -- insert into daily_status 
    INSERT INTO daily_status (date,service_id,time_up,time_down,time_maint,time_degraded) values (current_date-1,svc_id,up_duration,down_duration,maint_duration,degr_duration); 

    END LOOP the_loop; 

END 
+0

プロシージャ区切り記号( 'DELIMITER $$')を宣言しましたが、定義の最後には区切り文字はありません。ここにコードを貼り付ける際にあなたが忘れただけで、あなたの実際のコードには存在していないことを祈っています。 –

答えて

3

を理解していないあなたは、このような変数を割り当ててみました:

SELECT 
    up_duration := IFNULL(SUM(duration), 0) 
FROM daily_audit_summary 
WHERE service_id = svc_id 
    AND status = 'UP' 
    AND Date = current_date - 1 
GROUP BY 
    date, 
    service_id, 
    status; 

また、1つにすべての割り当てを組み合わせることができSELECT:

SELECT 
    up_duration := SUM(CASE status WHEN 'UP' THEN duration ELSE 0 END) 
    down_duration := SUM(CASE status WHEN 'DOWN' THEN duration ELSE 0 END) 
    maint_duration := SUM(CASE status WHEN 'MAINT' THEN duration ELSE 0 END) 
    degr_duration := SUM(CASE status WHEN 'DEGR' THEN duration ELSE 0 END) 
FROM daily_audit_summary 
WHERE service_id = svc_id 
    AND status = 'UP' 
    AND Date = current_date - 1 
GROUP BY 
    date, 
    service_id, 
    status; 

しかし、多分あなたはすべてのジョブを行うために、単一のステートメントを使用してカーソル(したがってループ)を避けることができます:

INSERT INTO daily_status (
    date, 
    service_id, 
    time_up, 
    time_down, 
    time_maint, 
    time_degraded 
) 
SELECT 
    d.Date, 
    s.service_id, 
    SUM(CASE das.status WHEN 'UP' THEN das.duration ELSE 0 END), 
    SUM(CASE das.status WHEN 'DOWN' THEN das.duration ELSE 0 END), 
    SUM(CASE das.status WHEN 'MAINT' THEN das.duration ELSE 0 END), 
    SUM(CASE das.status WHEN 'DEGR' THEN das.duration ELSE 0 END) 
FROM services s 
    CROSS JOIN (SELECT CURRENT_DATE - 1 AS Date) AS d 
    LEFT JOIN daily_audit_summary AS das 
    ON s.service_id = das.service_id 
    AND das.Date = d.Date; 
2

私はコードが進行中の作業で、原因の要件に、私は「Services_cur」カーソルを取り除くことはできません ...私はより良い説明を与えるために必要なことを推測します。

私が見ているのは、 "Services_Cur"の戻り値が "Loop"内の10個のレコードを返すときです。 のようなTABLEからSELECT INTO文を使用すると、 "SELECT F1 INTO MyVar from Atable where Afld = somevalue "LOOPは" Services Cur "カーソルのデータがなくなったかのように終了しますか? "SELECT 1234 INTO MyVar"を発行するとループが機能し、10個の結果(期待通り)が得られます。

私はMySqlのストアドプロシージャが新しく、FETCHESのループ内で一連の "テーブルのSELECT値"を実行している人の例は見つかりませんでした。

私は、これは、より良い任意の助け

おかげで、問題を説明するのに役立ちます願っています。

関連する問題