我正在编写一个存储过程来创建两个临时表做两个联合选择。 当单独使用第一个或第二个光标与另一个注释时,该过程有效, 但是当我运行查询以使用2个游标创建过程时,它会失败。我已经更改了代码以反映Ike Walker的建议。
这是脚本:
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),IN今天VARCHAR(20))READS SQL DATA BEGIN DECLARE小时INT ...
错误代码:1338
处理程序声明后的游标声明
执行时间:00:00:00:000
转机时间:00:00:00:000
总时间:00:00:00:000
我已尝试在所有声明部分的末尾放置两个继续处理程序,但它抱怨声明块重叠等。
你能告诉我我做错了什么吗?谢谢你的阅读。答案 0 :(得分:1)
在程序逻辑开始之前,您需要预先声明所有游标。
如果您按此顺序执行操作,则应该有效:
DECLARE variables
DECLARE cursors
DECLARE handlers
...
logic
答案 1 :(得分:1)
你为什么使用游标?只需使用联合,你就可以在没有tmp表的情况下轻松完成这项工作。
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;