开发者

Having trouble doing multiple cursors in a MySQL stored procedure

I'm writing a store procedure to create two temporary tables do an union select of the two. When using either first or second cursor alone with the other commented the pro开发者_JS百科cedure works, but when I run the query to create the procedure with the 2 cursors, it fails.i've changed the code to reflect Ike Walker's suggestion.

Here is the script:

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;

it gives this as error

Query : CREATE PROCEDURE joinemailsmsdailygraph(IN previousDay VARCHAR(20), IN today VARCHAR(20)) READS SQL DATA BEGIN DECLARE hours INT...

Error Code : 1338

Cursor declaration after handler declaration

Execution Time : 00:00:00:000

Transfer Time : 00:00:00:000

Total Time : 00:00:00:000

ive tried putting both continue handlers at the end of all declare section but it complains about declare block overlapping or so.

Can you please tell me what I'm doing wrong? Thanks for reading.


Why are you using cursors ? You could easily do this without a tmp table also by just using a union.

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;


You need to declare all of the cursors up front, before the logic of your procedure begins.

If you do things in this order it should work:

DECLARE variables
DECLARE cursors
DECLARE handlers
...
logic
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜