В последнем проекте начал применять хранимые процедуры в MySQL. После такой удобной реализации в Interbase/Firebird к ограниченной функциональности мускула пришлось немного попривыкнуть, но задачи стояли не такие сложные, чтобы особо сетовать. Простоеший проход по записям и несложные арифметические расчеты, сохраняемые во временную таблицу. Все алгоритмы – почти точная копия найденной в сети документации: по хранимым процедурам и курсорам в них…
И все было замечательно какое-то время, после чего начались странности…
Очередная процедура, написанная строго по документации и ничем технически не отличающаяся от других вдруг была замечена в воровстве результатов.
В теле были применены проверенные неоднократно конструкции:
BEGIN
DECLARE no_more BOOLEAN DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more = TRUE;OPEN reconciled_docs;
docs_loop:
LOOP
FETCH reconciled_docs INTO v_dochead_id, v_ref_no, v_doc_date, v_doc_amount, v_cheque_no, v_from_id, v_to_id;
IF no_more THENLEAVE docs_loop;
END IF;
/* код вырезан */
END LOOP docs_loop;
CLOSE reconciled_docs;
END;
Запрос из курсора должен был возвращать, скажем, 6 записей. Однако, пройдя по двум из них, MySQL убежденно говорил “записей там больше нет” и из цикла выходил. В других случаях он точно так же показывал 1 запись и сваливал. Трейс в dbForge Studio for MySQL показывал, что в очередной раз запись выбирается, новые значения в переменные записываются, но тем не менее условие IF no_more THEN выполняется и цикла прерывается.
Я всякое перепробовал, но мускул упорно говорил, что оставшиеся Х записей в курсоре отсутствуют. Этот бред я прикончил тупо:
BEGIN
DECLARE prev_id INT;OPEN reconciled_docs;
docs_loop:
LOOP
FETCH reconciled_docs INTO v_dochead_id, v_ref_no, v_doc_date, v_doc_amount, v_cheque_no, v_from_id, v_to_id;
IF v_dochead_id = prev_id THENLEAVE docs_loop;
END IF;
SET prev_id = v_dochead_id;
Так оно работает, и пока все устраивает, однако меня все же терзает вопрос: почему конструкция с CONTINUE HANDLER, неоднократно воспетая в разных доках по MySQL, так интересно меня подставила? Почему 2 записи? Почему не одна, не ноль, не Х-1, а именно 2?
Комментарии