MySQL:循环游标结果提前结束

Jor*_*alo 5 mysql trigger cursors

我正在执行一个遍历游标结果的循环。代码位于触发器函数中,重要的部分如下所示:

编辑:对不起,愚蠢的错误。删除“one_table”后执行触发器。这与我在触发器代码中执行“删除”或“更新”操作的表不同(参见下面的第二个清单)

create trigger my_trigger after delete on one_table
for each row 
begin 

declare my_value int; 
declare num_rows int default 0; 
declare done int default false; 
declare my_cursor cursor for select value from table where condition; 
declare continue handler for sqlstate '02000' set done = 1; 

open my_cursor; 
select found_rows() into num_rows; 

-- This is just for debugging 
insert into log_table(key, value) values('foo', num_rows); 

if num_rows > 0 then: 
  repeat 
    fetch my_cursor into my_value; 
    -- Do stuff 
  until done end repeat; 
end if; 

close my_cursor; 

end 
Run Code Online (Sandbox Code Playgroud)

循环应该执行 11 次,因为查询返回 11 个值。这由“插入”子句检查。var 'num_rows' 等于 11。但问题是循环只执行了 3 次。

这些数字 (11, 3) 并不重要。如果我更改查询以返回不同数量的结果,问题仍然存在:循环在预定之前结束。

有什么意义吗?我可能会在循环内做一些导致循环结束的事情(“做事”部分)。这是唯一对我来说听起来合乎逻辑的事情。

编辑:我包括“做东西”部分。问题可能是因为,在这部分中,执行了一些“选择”语句。当其中一个句子返回空结果时,将执行定义的处理程序,将 done 设置为“true”并中断循环。

“做东西”部分是这样的:

select some_value into some_field from other_table where some_conditions;

if (some_field is null) then
  delete from my_table where my_condition;
else
  update my_table set key1 = value1 where condition1;
Run Code Online (Sandbox Code Playgroud)

提前致谢,并致以最诚挚的问候,

Jor*_*alo 2

解决了。如前所述,问题是内部的“SELECT INTO...”语句返回 0 条记录,触发 CONTINUE HANDLER 并将 did 设置为 TRUE。我通过在从游标获取数据之前放置“set done = false”来修复此问题,如http://dev.mysql.com/doc/refman/5.0/en/cursors.html中的建议(David Bergan 在 2 月发表的评论) 2012 年 23 日晚上 10:00)。

所以,代码最终看起来像

create trigger my_trigger after delete on one_table
for each row 
begin 

declare my_value int; 
declare num_rows int default 0; 
declare done int default false; 
declare my_cursor cursor for select value from table where condition; 
declare continue handler for not found set done = true; 

open my_cursor; 

my_loop: loop

    set done = false;

    fetch my_cursor into my_value; 

    if done then
      leave my_loop;
    end if;


    select some_value into some_field from other_table where some_conditions;
    if (some_field is null) then
        delete from my_table where my_condition;
    else
        update my_table set key1 = value1 where condition1;
    end if;
end loop my_loop; 

close my_cursor; 

end
Run Code Online (Sandbox Code Playgroud)

感谢 RolandoMySQLDBA 的回答。