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