2012-09-06 2 views
13

Ich bin durch ein Cursor Ergebnis in einer MYSQL gespeicherten Prozedur durchlaufen. Ich stehe vor einem Problem, dass die Schleife immer zweimal durch den letzten Datensatz läuft. Hier ist mein Code,MYSQL Cursorschleife, läuft eine Extrarunde, warum?

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; 

Mittel, wenn ich 3 Datensätze haben, Schleife 4 mal läuft, wenn es 10 Datensätze Schleife läuft 11mal usw. Jede Idee, was geschieht hier?

+1

Dies kann helfen -> [Cursor zweimal letzte Zeile Iterieren] (http://forums.mysql.com/read.php?102,155063,155063) – Kermit

+0

Ja, das hat wirklich funktioniert. Danke – Thanu

+0

der Link fehlt jetzt – ejectamenta

Antwort

16

Der Handler, die not_found_creadit = 1 setzt, wird ausgelöst, wenn die FETCH kehrt keine Zeilen, aber Sie werden ihren Wert überprüft vorFETCH Ausführung, so dass der Hauptteil Ihrer Schleife wird eine zusätzliche Zeit ausgeführt werden, wenn die FETCH ausfällt, dann Die Schleife endet am Anfang der nächsten Iteration.

neu ordnen Sie den Code, den Wert Ihrer Variable sofort nach zu überprüfen, die 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; 


Bedenken Sie auch die Schreibweise Ihres Variable

-1

-not_found_credit Korrektur müssen Sie RICHTIGE ART, WEIL ich STANDARD SCHREIBE (ich weiß nicht, was Sie im Tabellenkredit haben). End If U-Tabelle erstellen TempTable

verwenden
TRUNCATE TempTable; 

Schreiben Sie bitte Beispiel

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

ofcourse Typ schlecht :)

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