17

我正在遍历 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 次,等等。知道这里发生了什么吗?

4

2 回答 2

24

设置的处理程序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

于 2012-09-06T01:11:27.157 回答
-1

你必须正确的类型,因为我写的是默认值(我不知道你在表信用中有什么)。End If U 创建表 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 $$
于 2012-09-06T12:00:42.490 回答