17

MYSQLストアドプロシージャのカーソル結果セットをループしています。私は、ループが常に最後のレコードを2回実行するという問題に直面しています。これが私のコードです、

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回実行される、などです。ここで何が起こっているのでしょうか。

4

2 に答える 2

24

を設定するハンドラーは、行が返されないnot_found_creadit = 1ときに起動されますが、実行する前にFETCHその値をチェックしているため、ループの本体は失敗したときに1回余分に実行され、ループループはの開始時に終了します反復。FETCHFETCH

コードを再配置して、:の直後の変数の値を確認します。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

于 2012-09-06T01:11:27.157 に答える
-1

私はデフォルトを書くので、タイプを修正する必要があります(テーブルクレジットに何があるのか​​わかりません)。End If U create table TempTable use

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 $$
于 2012-09-06T12:00:42.490 に答える