2010-08-11 134 views
26

我有一個存儲過程,不需要返回任何值。它運行順暢,沒有任何問題。但是,它在完成運行後輸出錯誤消息:如何擺脫「錯誤1329:沒有數據 - 零行取出,選擇或處理」

Error: No data - zero rows fetched, selected, or processed

我該如何擺脫此錯誤消息?

CREATE PROCEDURE `testing_proc`() 
    READS SQL DATA 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE l_name VARCHAR(20); 
    DECLARE my_cur CURSOR FOR 
     SELECT name FROM customer_tbl; 
    OPEN my_cur; 
     my_cur_loop: 
     LOOP FETCH my_cur INTO l_name; 
      IF done = 1 THEN 
       LEAVE my_cur_loop; 
      END IF; 
      INSERT INTO names_tbl VALUES(l_name); 
     END LOOP my_cur_loop; 
    CLOSE my_cur; 
END 
+1

沒有細節,我會第一個說 - 它可以被替換爲'INSERT INTO names_tbl SELECT name FROM CUSTOMER_TBL' =) – 2010-08-11 22:21:41

+0

感謝OMG小馬。在實際的代碼中「INSERT INTO names_tbl VALUES(l_name);」應該由200行代碼替換。我使用了這個簡化版本,因爲即使是這個簡化版本,我也會得到相同的錯誤。如果它幫助刪除錯誤消息,我可以輸出一個varchar作爲返回值。 – Babibo 2010-08-11 22:26:29

回答

23

您需要定義諸如繼續處理程序:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

所以它看起來像:

DECLARE done INT DEFAULT 0; 
DECLARE l_name VARCHAR(20); 
DECLARE my_cur CURSOR FOR 
    SELECT name FROM customer_tbl; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

OPEN my_cur; 
    my_cur_loop: 
    LOOP FETCH my_cur INTO l_name; 
     IF done = 1 THEN 
      LEAVE my_cur_loop; 
     END IF; 
     INSERT INTO names_tbl VALUES(l_name); 
    END LOOP my_cur_loop; 
CLOSE my_cur; 
34

我想你只是忘了在帖子下面一行:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

您的代碼是相關的ct,但是mysql的bug /奇怪行爲會導致即使處理它也會出現警告。如果您在過程的末尾添加一個「虛擬」語句來調用表並且成功,那麼可以避免這種情況,這將清除警告。循環結束後

SELECT name INTO l_name FROM customer_tbl LIMIT 1; 

:(見http://dev.mysql.com/doc/refman/5.5/en/show-warnings.html) 你的情況。 在MySQL 5.5.13上,警告在Linux和Windows上消失。 我評論MySQL的錯誤60840,我希望他們將來修復一段時間...

+0

謝謝你。這爲我解決了一個隱晦的問題 – Cruachan 2012-03-10 21:55:23

+0

包括一個虛擬選擇也爲我解決了這個問題。虛擬選擇必須位於外層功能中。用光標包含在函數中是不夠的。 – user984003 2012-05-08 11:33:12

+0

我有同樣的問題,你的解決方案爲我工作。謝謝 – 2013-05-31 00:16:18

1

我不知道這是否修復了遊標問題,但我遇到了這個警告與存儲的功能,發現如果你使用:

RETURN (SELECT x From myTable...); 

代替

SELECT x into myVar...return myVar 

我得到這個從這個有用的文檔: http://bugs.mysql.com/bug.php?id=42834

+0

非常感謝,它幫助我 – 2013-07-23 09:21:40

1

正常情況下,當您超出光標範圍時,會發生這種情況,因此請檢查FETCH聲明爲

+1

這應該是一個評論,而不是一個答案。檢查這個[metaSO問題](http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question)和[Jon Skeet:Coding Blog]( http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx)如何給出正確的答案。 – Yaroslav 2012-10-11 18:19:51

3

的循環條件我嘗試了這裏和全部解決方案,包括繼續處理程序爲我工作。我仍然在MySQL錯誤日誌中收到消息。我發現這也與我的「選擇......進入......」這是有道理的,但我真的認爲繼續處理程序將爲遊標工作。無論哪種方式,我發現使用「found_rows()」找出是否有任何行被返回完美工作。這意味着簡單的「select into」語句必須轉換爲光標,但它並不是很多工作,並且解決了問題。

DECLARE v_rowcount  integer unsigned; 
DECLARE cur_entries cursor for 
     select app_name, proc_name, error_code, sum(occurrences) occurrences 
     from that_table...; 
open cur_entries; 
set v_rowcount = found_rows(); 
if v_rowcount > 0 then 
    fetch cur_entries into v_app_name, v_proc_name, v_error_code, v_occurrences; 
    ... 
end if; 
close cur_entries; 

我寫這在我的個人博客在這裏:http://tinky2jed.wordpress.com/technical-stuff/mysql/mysql-no-data-zero-rows-fetched-how-to-code-for-it/

7

我遇到了這一點,並拉出我的頭髮,直到我在official mysql docs

Before MySQL 5.6.3, if a statement that generates a warning or error causes a condition handler to be invoked, the handler may not clear the diagnostic area. This might lead to the appearance that the handler was not invoked. The following discussion demonstrates the issue and provides a workaround.

過這個跑點擊該鏈接,滾動到底部的細節,但修復是包括一個成功的選擇內部繼續處理程序:

DECLARE CONTINUE HANDLER FOR NOT FOUND 
    BEGIN 
     SELECT 1 INTO @handler_invoked FROM (SELECT 1) AS t; 
    END;