数据库
首页 > 数据库> > MySQL:循环游标结果提前结束

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

作者:互联网

我正在执行一个迭代游标结果的循环.代码在触发器函数内部,重要的部分看起来像这样:

编辑:对不起,愚蠢的错误.删除“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 

循环应该执行11次,因为查询返回11个值.这由’insert’子句检查. var’num_rows’等于11.但问题是循环只执行3次.

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

它有意义吗?我可以在循环内部做一些事情(‘do stuff’部分)导致循环结束.这是唯一对我来说听起来很合理的东西.

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

“Do stuff”部分是这样的:

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;

在此先感谢,并提出最好的问候,

解决方法:

你应该严格检查循环内循环的结束

create trigger my_trigger after delete on my_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; 

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

cursor_loop:repeat 
    if done then
        leave cursor_loop;
    end if;
    fetch my_cursor into my_value; 
    -- Do stuff 
    until done
end repeat; 

close my_cursor; 

end 

这也将消除必须检查计数

试试看 !!!

看着你的伪代码

create trigger my_trigger after delete on my_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; 

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

cursor_loop:repeat 
    if done then
        leave cursor_loop;
    end if;
    fetch my_cursor into my_value; 
    -- Do stuff 

    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;

    until done
end repeat; 

close my_cursor; 

end 

当你在同一个表上的DELETE后触发器中间时,在my_table上执行UPDATE可能不是一个好主意.另外,请注意您在if(some_field为null)下也会在同一个表上导致DELETE.

您可能最好将此触发器写为存储过程并手动使用Call to it而不是在同一个表上嵌套DELETE表内的UPDATE.

标签:mysql,cursors,trigger
来源: https://codeday.me/bug/20190806/1594658.html