从表格里面的SELECT语句循环强制游标到EXIT

时间:2012-02-27 06:25:14

标签: mysql sql stored-procedures

MySQL存储过程的新功能。 如果我取消注释4个SELECT行(下面)中的任何一个,那么例程EXITS退出FETCH循环。不明白为什么

-- --------------------------------------------------------------------------------
-- 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

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:2)

我想我需要做出更好的解释...... 该代码是一项正在进行的工作,由于要求,我无法摆脱“Services_cur”光标。

我发现的是,当“Services_Cur”的查询返回10条记录并且在“循环”中时如果我使用来自TABLE的SELECT INTO语句,例如 “从Atable中选择F1 INTO MyVar,其中Afld = somevalue”LOOP退出,好像“Services Cur”光标没有数据一样??? 如果我发出“SELECT 1234 INTO MyVar”循环工作,我得到10个结果(按预期)。

我是MySql的存储过程的新手,并且找不到某人在FETCHES的循环中执行一系列“表的SELECT值”的示例。

我希望这有助于更好地解释问题

感谢您的帮助。