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)
提前致谢,并致以最诚挚的问候,
解决了。如前所述,问题是内部的“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 的回答。