2011-02-23 50 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