Подтвердить что ты не робот

Цикл курсора MYSQL, запускает один дополнительный раунд, почему?

Я перебираю результат набора курсора в хранимой процедуре MYSQL. Я столкнулся с проблемой, которая заключается в том, что цикл всегда проверяет последнюю запись дважды. Вот мой код,

BEGIN
DECLARE not_found_creadit INT DEFAULT 0;

DECLARE cur_credit CURSOR FOR 
SELECT customer_id, amount, status, user_type, employee, note FROM credit WHERE status = 'approved' AND customer_id = int_cust_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET not_found_creadit = 1;
OPEN cur_credit;
  SET not_found_creadit = 0;
  credit_loop : LOOP 
      IF not_found_creadit THEN
        CLOSE cur_credit;
        LEAVE credit_loop;
      END IF;
      FETCH cur_credit INTO vc_customer, dec_amount, vc_status, vc_user_type, vc_emp, vc_note;
      SELECT vc_customer, dec_amount, vc_status, vc_user_type, vc_emp, vc_note;
      ......
      ......
  END LOOP;
END;

Означает, что если у меня есть 3 записи, цикл выполняется 4 раза, если это 10 циклов записи, 11 раз и т.д. Любая идея, что происходит здесь?

4b9b3361

Ответ 1

Обработчик, который устанавливает not_found_creadit = 1, запускается, когда FETCH не возвращает строки, но вы проверяете его значение перед выполнением FETCH, поэтому основная часть вашего цикла будет выполнять одно дополнительное время, когда FETCH не работает, тогда цикл цикла выходит в начале следующей итерации.

Переупорядочите свой код, чтобы проверить значение переменной сразу после FETCH:

credit_loop : LOOP 
    FETCH cur_credit INTO vc_customer, dec_amount, vc_status, vc_user_type, vc_emp, vc_note;
    IF not_found_creadit THEN
        CLOSE cur_credit;
        LEAVE credit_loop;
    END IF;
    SELECT vc_customer, dec_amount, vc_status, vc_user_type, vc_emp, vc_note;
    ......
    ......
END LOOP;


Кроме того, рассмотрите исправление орфографии вашей переменной до not_found_credit

Ответ 2

ВЫ ДОЛЖНЫ ИЗМЕНИТЬ ТИП ПОТОМУ ЧТО Я НАПИСАЛ ПО УМОЛЧАНИЮ (я не знаю, что у вас есть в таблице кредита). End Если U create table TempTable использует

TRUNCATE TempTable;

Пожалуйста, перепишите пример

CREATE CREATE TEMPORARY TABLE TempTable (`Id` int(11) NOT NULL auto_increment,
  `customer_id` int(11) NOT NULL,
  `amount` int(11) NOT NULL,
  `status` varchar(1000) NOT NULL,
  `user_type` int(11) NOT NULL default '0',
  `employee` varchar(1000) NOT NULL,
  PRIMARY KEY  (`customer_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ;");

тип курса плохой:)

 DELIMITER $$
    DROP PROCEDURE IF EXISTS CursorX $$
    CREATE PROCEDURE `CursorX`()
    BEGIN    
            DECLARE xCustomerId int(11);  
            DECLARE xStatus   int(11);
            DECLARE xUserType  varchar(255);
            DECLARE xEmployee  varchar(255);
            DECLARE xNote varchar(255);  
            DECLARE i int(11);
            DECLARE recordNotFound INTEGER DEFAULT 0;
            DECLARE cur_credit CURSOR FOR SELECT customer_id, amount, status, user_type, employee, note FROM credit WHERE status = 'approved' AND customer_id = int_cust_id;
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET recordNotFound = 1;

            DROP TEMPORARY TABLE IF EXISTS TempTable;
            CREATE TEMPORARY TABLE TempTable AS(SELECT * FROM credit);

            OPEN cur_credit;
            set not_found_creadit = 0;
            credit_loop: LOOP
            SET i = i +1;
                FETCH cur_credit INTO xCustomerId,xStatus,xUserType,xEmployee,xNote;
                IF not_found_creadit THEN
                    LEAVE credit_loop;
                 END IF;
            END LOOP credit_loop;
            CLOSE cur_credit;
    select * FROM TempTable;

    END $$