mysql存储过程游标嵌套问题讨论

昨天发了一个帖子,是关于mysql存储过程游标问题的,感谢“沧海居士”的回复,但问题仍然没有解决。后来在网上找了一篇相关文章,测试通过,但修改后发现问题,发上来请大家看看问题出在那里?

网上找的原帖:
关于MySQL游标的嵌套使用
作者:天涯 来源:中国自学编程网 发布日期:1242725065  

前几天群里有人问MySQL的游标能不能嵌套使用,想当然地以为不能,后来试了下,居然可以,唉,不能随便想当然啊。例子如下:
CREATE PROCEDURE curdemo()
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
declare done1,done2 int default 0;
declare name1,name2 varchar(20);
declare id1,id2 int;

declare cur1 cursor for select id,name from test1;
declare continue handler for not found set done1 = 1;

open cur1;

repeat
fetch cur1 into id1, name1;
if not done1 then

#测试时删除下面一条语句,因为与后面的测试无大关系
#insert into test3(name) values(name1);

begin
declare cur2 cursor for select id,name from test2;
declare continue handler for not found set done2 = 1;
open cur2;
repeat
fetch cur2 into id2,name2;
if not done2 then
insert into test3(name) values(name2);
end if;
until done2 end repeat;
close cur2;
set done2=0;
end;
end if;
until done1 end repeat;
close cur1;

commit;
END;

测试数据:
表test1:
name       id
麻六        1
田七        2
王八        3

表test2:
name       id
麻六        1
普九        2

测试结果:应该是正确的,将表test2的name写3次到表test3。
        麻六
        普九
        麻六
        普九
        麻六
        普九

作者: yqlyd   发布时间: 2011-05-12

1、将语句:
declare cur2 cursor for select id,name from test2
改成:
declare cur2 cursor for select id,name from test2 where name=name1;

测试结果为:应该也是正确的
       麻六

2、将语句:if not done2 then
   改成:if name2  is not null then
测试结果如下:
        麻六
        麻六
        麻六
        麻六

这里就好象有问题?

作者: yqlyd   发布时间: 2011-05-12

将语句:
if not done2 then
insert into test3(name) values(name2);
end if;

改成:
if name2  is not null then
        insert into test3(name) values(name1);
else
        insert into test4(name) values(name1);
end if;
测试结果为:
表test3:
        麻六
        麻六
        田七
        王八
表test4为空

作者: yqlyd   发布时间: 2011-05-12

我真看不懂为啥你一定要用嵌套循环呢?

为何不考虑一条语句搞定呢,难道是为了测试嵌套游标?


     declare cur2 cursor for select id,name from test2;
     declare continue handler for not found set done2 = 1;
     open cur2;
     repeat
          fetch cur2 into id2,name2;
          if not done2 then
             insert into test3(name) values(name2);
          end if;
     until done2 end repeat;

     close cur2;
     set done2=0;
     
     
     替换成一条命令:
     
     INSERT INTO test3(name) SELECT name FROM test2;

作者: jinguanding   发布时间: 2011-05-12

当然不是
是因为需要依据SELECT name FROM test2这条语句返回的结果决定。
如果存在则行更新,不存在则插入。

作者: yqlyd   发布时间: 2011-05-12



QUOTE:原帖由 yqlyd 于 2011-5-12 14:03 发表
当然不是
是因为需要依据SELECT name FROM test2这条语句返回的结果决定。
如果存在则行更新,不存在则插入。

不是有外部游标循环的嘛,难道内部查询到的name会出现多个???

作者: jinguanding   发布时间: 2011-05-12