首页 > 解决方案 > 在 mySQL 过程循环中处理未找到的数据

问题描述

我想我正在缩小我的问题。我有一个只触发一次的循环:

DELIMITER $$

DROP PROCEDURE IF EXISTS `thread_updates` $$
CREATE PROCEDURE `thread_updates`()
BEGIN

DECLARE done INT DEFAULT 0;
DECLARE my_curr_id INT DEFAULT NULL;
-- DECLARE other vars
DECLARE fixer_cursor CURSOR FOR
  SELECT DISTINCT(id)
  FROM log
  WHERE date >= '2018-01-01';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN fixer_cursor;
REPEAT
  FETCH fixer_cursor INTO my_curr_id;
  IF NOT done THEN
    SELECT data FROM table WHERE id = my_curr_id; -- This may not exist 
    -- Do other stuff with 'data' or NULL from above
  END IF;
UNTIL done END REPEAT;
CLOSE fixer_cursor;
END $$
DELIMITER ;

我认为问题可能出在IF NOT done THEN循环内部,我有一些选择语句可能试图选择不存在(未找到)的结果。

这很好(对我来说),因为逻辑继续在这些位置使用 NULL 值,但我怀疑我CONTINUE HANDLER FOR NOT FOUND正在捕捉NOT FOUND警告,即这些选择抛出循环内,因此过早停止整个循环。

如何NOT FOUND仅在光标上收听警告?

或者,如何NOT FOUND在循环内的 MAYBE FOUND 选择语句中抑制警告,以便循环继续?

标签: mysqlloopsstored-procedures

解决方案


我想我已经通过在循环中实现一个计数器而不是依赖于NOT FOUND处理程序来解决这个问题:

DELIMITER $$

DROP PROCEDURE IF EXISTS `thread_updates` $$
CREATE PROCEDURE `thread_updates`()
BEGIN

DECLARE my_total INT DEFAULT NULL; -- Declare total
DECLARE my_counter INT DEFAULT 0; -- Declare counter starting at 0
DECLARE my_curr_id INT DEFAULT NULL;
-- DECLARE other vars
DECLARE fixer_cursor CURSOR FOR
  SELECT DISTINCT(id)
  FROM log
  WHERE date >= '2018-01-01';

OPEN fixer_cursor;

SELECT FOUND_ROWS() INTO my_total; -- Get total number of rows

my_fixerloop: LOOP

  FETCH fixer_cursor INTO my_curr_id;
  IF my_counter >= my_total THEN -- Compare counter to total
    CLOSE fixer_cursor;
    LEAVE my_fixerloop;
  END IF;

  SET my_counter = my_counter + 1; -- Increment by one for each record

  SELECT data FROM table WHERE id = my_curr_id; -- This may not exist 
  -- Do other stuff with 'data' or NULL from above

END LOOP;
END $$
DELIMITER ;

推荐阅读