2011-02-23 126 views
0

我正在编写一个存储过程以创建两个临时表,并执行两个联合选择。 当第一个或第二个游标与另一个游标一起使用时,其他注释过程可以运行,但是当我运行查询以创建2个游标的过程时,它失败了。我已更改代码以反映Ike Walker的建议。在MySQL存储过程中执行多个游标时遇到问题

下面是脚本:

DELIMITER // 

DROP PROCEDURE IF EXISTS joinemailsmsdailygraph// 

CREATE PROCEDURE joinemailsmsdailygraph(IN previousDay VARCHAR(20), IN today VARCHAR(20)) 
READS SQL DATA 

BEGIN 

DECLARE hours INT; 
DECLARE sms INT; 
DECLARE email INT; 
DECLARE smsdone INT DEFAULT 0; 
DECLARE emaildone INT DEFAULT 0; 


DECLARE cursorsms CURSOR FOR SELECT HOUR(sm.date_created) AS `HOUR OF DAY`, COUNT(*) AS smscount 
FROM sms_message_delivery smd 
JOIN sms_message sm ON sm.sms_message_id = smd.sms_message_id 
WHERE DATE(sm.date_created) >= DATE(previousDay) AND DATE(sm.date_created) < DATE(today) 
GROUP BY HOUR(sm.date_created); 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET smsdone =1; 


DECLARE cursoremail CURSOR FOR SELECT HOUR(em.date_created) AS `HOUR OF DAY`, COUNT(*) AS emailcount 
FROM email_message_delivery emd 
LEFT JOIN email_message em ON emd.email_message_id=em.email_message_id 
WHERE DATE(em.date_created) >= DATE(previousDay) AND DATE(em.date_created) < DATE(today) 
GROUP BY HOUR(em.date_created); 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET emaildone =1; 

DROP TEMPORARY TABLE IF EXISTS tempsms; 
CREATE TEMPORARY TABLE tempsms (hours_day INT, sms_count INT, email_count INT); 

OPEN cursorsms; 
sms_loop: LOOP 

FETCH cursorsms INTO hours , sms; 

IF smsdone = 1 THEN 
LEAVE sms_loop; 
END IF; 

INSERT INTO tempsms (hours_day, sms_count) VALUES (hours, sms); 

END LOOP sms_loop; 
CLOSE cursorsms; 


DROP TEMPORARY TABLE IF EXISTS tempemail; 

CREATE TEMPORARY TABLE tempemail (hours_day INT , sms_count INT , email_count INT); 

OPEN cursoremail; 
email_loop: LOOP 

FETCH cursoremail INTO hours, email; 

IF emaildone=1 THEN 
LEAVE email_loop; 
END IF; 

INSERT INTO tempemail(hours_day, email_count) VALUES(hours, email); 

END LOOP email_loop; 
CLOSE cursoremail; 


SELECT hours_day, sms_count , email_count FROM tempsms 
UNION 
SELECT hours_day, sms_count, email_count FROM tempemail; 

END// 
DELIMITER; 

它使这是错误

查询:CREATE PROCEDURE joinemailsmsdailygraph(IN previousDay VARCHAR(20),在今天VARCHAR(20))读取SQL数据BEGIN DECLARE小时INT ...
错误代码:1338后
游标声明处理器声明
执行时间:00:00:00:000
传输时间:00:00:00:000
总时间:00:00:00:000

香港专业教育学院试图把双方继续处理所有月底宣布部分,但它抱怨声明块重叠或者。

你能告诉我我做错了什么吗?谢谢阅读。

+0

您使用光标而不是选择进入的任何特定原因? – 2011-02-23 22:31:09

回答

1

你为什么要使用游标?你也可以通过使用联合来轻松完成这个工作。

drop procedure if exists join_email_sms_daily_graph; 

delimiter # 

create procedure join_email_sms_daily_graph 
(
in previousDay varchar(20), 
in today varchar(20) 
) 
begin 

create temporary table tmp 
(
hours_day int unsigned, 
sms_count int unsigned default 0, 
email_count int unsigned default 0 
)engine=memory; 

insert into tmp (hours_day, sms_count) 
select 
hour(sm.date_created) as hours_day, 
count(*) AS sms_count 
from 
sms_message_delivery smd 
join sms_message sm ON sm.sms_message_id = smd.sms_message_id 
where 
date(sm.date_created) >= date(previousDay) and date(sm.date_created) < date(today) 
group by 
hour(sm.date_created); 

insert into tmp (hours_day, email_count) 
select 
hour(em.date_created) as hours_day, 
count(*) AS email_count 
from 
email_message_delivery emd 
left join email_message em ON emd.email_message_id=em.email_message_id 
where 
date(em.date_created) >= date(previousDay) and date(em.date_created) < date(today) 
group by 
hour(em.date_created); 

select * from tmp; 

drop temporary table if exists tmp; 

end# 

delimiter; 
+0

f00非常感谢。你的解决方案的工作只是让我意识到,我想要实现不能用这种方法完成。感谢 – 2011-02-24 11:19:25

+0

没有probs - 希望你工作一切:) – 2011-03-11 00:30:07

1

在过程的逻辑开始之前,您需要预先声明所有游标。

如果你在这个顺序做的事情它应该工作:

DECLARE variables 
DECLARE cursors 
DECLARE handlers 
... 
logic 
+0

嗨艾克,你可以详细解释一下你的解释,如果可能的话,用一个小小的工作例子。我会比gratefull.thanks;) – 2011-02-24 11:28:54