2012-09-06 14 views
13

Estoy recorriendo un resultado de cursor en un procedimiento almacenado MYSQL. Me enfrento a un problema que es que el ciclo siempre se ejecuta a fondo el último registro dos veces. Aquí está mi código,Cursor de cursor MYSQL, ejecuta una ronda extra, ¿por qué?

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; 

significa que si tengo 3 registros, bucle se ejecuta 4 veces, si se trata de bucle de 10 registros se ejecuta 11 veces, etc. Alguna idea de qué está sucediendo aquí?

+1

Esto puede ayudar -> [cursor de la iteración dos veces en última fila] (http://forums.mysql.com/read.php?102,155063,155063) – Kermit

+0

Sí, eso realmente funcionó. Gracias – Thanu

+0

el enlace ahora está perdido – ejectamenta

Respuesta

16

El controlador, que establece not_found_creadit = 1, se activa cuando el FETCH no devuelve ninguna fila, pero se está comprobando su valor antes ejecutar FETCH, por lo que el cuerpo principal de su ciclo se ejecutará un tiempo extra cuando el FETCH falla, el loop loop sale al comienzo de la siguiente iteración .

reorganizar su código para comprobar el valor de la variable de inmediato después la 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; 


Además, considerar la corrección de la ortografía de su variable para not_found_credit

-1

USTED DEBE CORRECTO TIPO PORQUE ESCRIBO PREDETERMINADO (no sé lo que tiene en la tabla de crédito). End If U Crear una tabla TempTable utilizar

TRUNCATE TempTable; 

favor reescribir ejemplo

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 ;"); 

supuesto tipo es malo :)

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 $$