Как избавиться от "Ошибка 1329: Нет данных - нулевые строки выбраны, выбраны или обработаны"
У меня есть хранимая процедура, которая не нуждается в возврате каких-либо значений. Он работает гладко и без проблем. Однако после завершения запуска он выдает сообщение об ошибке:
Ошибка: нет данных - нулевые строки выбраны, выбраны или обработаны
Как я могу избавиться от этого сообщения об ошибке?
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
Я думаю, вы просто забыли включить следующую строку в свой пост:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
Ваш код верен, но ошибка/странное поведение mysql вызывает появление предупреждения, даже если оно было обработано. Вы можете избежать этого, если вы добавите оператор "dummy" в конец вашей процедуры, который вызывает таблицу и будет успешным, это очистит предупреждение. (См. 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, и я надеюсь, что они исправит это некоторое время в будущем...
Ответ 2
Вам нужно определить обработчик continue:
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;
Ответ 3
Я столкнулся с этим и вытащил свои волосы, пока не натолкнулся на это в официальных mysql docs
Перед MySQL 5.6.3, если инструкция, которая генерирует предупреждение или ошибку вызывает вызов обработчика условия, обработчик может не очищать диагностической области. Это может привести к появлению обработчик не был вызван. Следующее обсуждение демонстрирует выдает и обеспечивает обходное решение.
Нажмите ссылку и прокрутите страницу вниз, чтобы узнать подробности, но исправить было включение успешного выбора INSIDE the CONTINUE HANDLER:
DECLARE CONTINUE HANDLER FOR NOT FOUND
BEGIN
SELECT 1 INTO @handler_invoked FROM (SELECT 1) AS t;
END;
Ответ 4
Я попробовал решения здесь, и никто, включая обработчик продолжения, работал у меня. Я все еще получаю сообщения в журнале ошибок 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/
Ответ 5
Я не знаю, исправляет ли это проблему курсора, но я столкнулся с этим предупреждением с сохраненной функцией и обнаружил, что если вы используете:
RETURN (SELECT x From myTable...);
вместо
SELECT x into myVar...return myVar
Я получил это от этого полезного документа:
http://bugs.mysql.com/bug.php?id=42834
Ответ 6
Обычно это происходит, когда вы превышаете диапазон курсора, поэтому проверяйте условия цикла, в которых оператор FETCH