我有一个存储过程,不需要返回任何值。它运行顺畅,没有任何问题。但是,它在完成运行后输出错误消息:
错误:无数据 - 提取,选择或处理零行
如何摆脱此错误消息?
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
答案 0 :(得分:38)
我猜您只是忘了在帖子中包含以下内容:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
您的代码是正确的,但是mysql的错误/奇怪行为会导致警告出现,即使它已被处理。如果在程序结束时添加“虚拟”语句来调用表并且成功,则可以避免这种情况,这将清除警告。 (见http://dev.mysql.com/doc/refman/5.5/en/show-warnings.html) 在你的情况下:
SELECT name INTO l_name FROM customer_tbl LIMIT 1;
循环结束后。 在MySQL 5.5.13上,警告在Linux和Windows上消失。 我评论了MySQL Bug 60840,我希望他们将来会修复它......
答案 1 :(得分:26)
您需要定义一个继续处理程序,如:
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;
答案 2 :(得分:8)
我遇到了这个并拉了我的头发,直到我在official mysql docs
中遇到了这个在MySQL 5.6.3之前,如果语句产生警告或错误 导致调用条件处理程序,处理程序可能无法清除 诊断区域。这可能会导致外观 处理程序未被调用。以下讨论演示了 问题并提供解决方法。
单击链接并滚动到底部以获取详细信息,但修复是包括成功选择INSIDE CONTINUE HANDLER:
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
SELECT 1 INTO @handler_invoked FROM (SELECT 1) AS t;
END;
答案 3 :(得分: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/
答案 4 :(得分:1)
我不知道这是否修复了游标问题,但是我使用存储的函数遇到了这个警告,发现如果你使用:
RETURN (SELECT x From myTable...);
而不是
SELECT x into myVar...return myVar
我从这个有用的文档得到了这个: http://bugs.mysql.com/bug.php?id=42834
答案 5 :(得分:1)
通常在超出游标范围时会发生这种情况,因此请检查FETCH
语句所在的循环条件
答案 6 :(得分:0)
我在代码中遇到了同样的错误,我意识到我没有增加我的循环变量(使用while循环),因此循环将变为无限。
在您的代码中,您也没有将“ done”设置为1,因此我认为代码显示错误。
在下面的代码中,我添加了变量“ count”,而不是变量“ done”,该变量用表中的记录数初始化,并在每次插入后减小。当count = 0时,循环终止:
CREATE PROCEDURE `testing_proc`()
READS SQL DATA
BEGIN
DECLARE count INT;
DECLARE l_name VARCHAR(20);
SELECT count(*) into count from customer_tbl;
DECLARE my_cur CURSOR FOR
SELECT name FROM customer_tbl;
OPEN my_cur;
my_cur_loop:
LOOP FETCH my_cur INTO l_name;
INSERT INTO names_tbl VALUES(l_name);
SET count = count - 1;
IF count = 0 THEN
LEAVE my_cur_loop;
END IF;
END LOOP my_cur_loop;
CLOSE my_cur;
END
我希望这会有所帮助!