MySQL のストアド プロシージャで同じ問題が発生しました。特定の列に null 値を持つテーブルからすべてのレコードを取得し、別のテーブルからその値を入力することになっていました。ただし、1 つのレコードの後に停止しました。
CREATE PROCEDURE `updateRecord`()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE recordId, newValue INT;
DECLARE current_record CURSOR FOR SELECT id FROM A where b_id is null;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN current_record;
main_loop: LOOP
FETCH current_record INTO recordId;
IF done THEN
LEAVE main_loop;
END IF;
-- fetching some value from table b
select id into newValue from B where ...
-- setting new value in record
update A set b_id = newValue where id = recordId;
END LOOP;
END
答えは、カーソルが行を返さなかった場合だけでなく、テーブル B の選択が行を返さなかった場合にも、「見つからないハンドラー」が実行されるということです。私の解決策は、ハンドラーによって設定された2番目の変数を使用し、選択後に「完了」変数をリセットすることでした:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE, noBfound = TRUE;
[...]
select id into newValue from B where ...
IF (noBfound = TRUE) THEN
SET done = FALSE;
END IF;
[...]
追加:選択後に「完了」をリセットするだけで、2番目の変数なしで実行できることは明らかです。
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
[...]
select id into newValue from B where ...
SET done = FALSE;
[...]