2012-02-27 37 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

你已經聲明瞭proc分隔符('DELIMITER $$'),但是在定義的最後沒有一個。我希望你只有在這裏粘貼代碼時纔會錯過它,它出現在你的實際代碼中。 – 2012-02-27 08:17:51

回答

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; 

您也可以將所有任務合併成一個單一的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」返回說10條記錄,並在「循環」內如果我從表中使用SELECT INTO語句,如 「SELECT F1 INTO MyVar from Atable where Afld = somevalue「LOOP退出,就好像」Services Cur「光標不在數據中一樣? 如果我發出「選擇1234 INTO MyVar」循環工作,我得到10個結果(如預期)。

我是MySql的新存儲過程,無法找到某個人在獲取循環內執行一系列「SELECT value for table」的示例。

我希望這有助於解釋這個問題更好

感謝您的幫助。