这是我的mysql程序的一部分:
declare myCursor cursor for select body,id from posts where body like '%Possible Duplicate%' limit 10 offset 11;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
open myCursor;
myloop: loop
fetch myCursor into mybody, myid;
if finished = 1 then leave myloop;
end if;
set Dupdup = 1;
set mytitle = regexp_substr(mybody,'.+?(?=</a>)');
select id into Dupdup from posts where title like mytitle;
update posts set dupicateId = Dupdup, isDuplicate = 1 where id = myid;
end loop myloop;
close myCursor;
我有一个很奇怪的问题。每当
select id into Dupdup from posts where title like mytitle;
不返回 id
时,它就会在下一次迭代时退出循环。我想当 DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
没有返回 select id into Dupdup from posts where title like mytitle;
时,id
就会被执行。我想不出其他原因了
有办法解决这个问题吗?
我遇到了类似的问题,这是由于循环内的
SELECT ... INTO
查询没有找到某个迭代的记录。由于某种原因,发生这种情况时 MySQL 会跳出循环。
试试这个:确定光标停止循环之前所在的最后一行。您可以将此查询添加为循环内的第一行:
SELECT mybody, myid;
并运行它(您可能需要注释掉 UPDATE 查询)。最后打印的结果将是有问题的行。现在,从该行获取值并尝试在插入该值的情况下单独运行
SELECT ... INTO
查询。删除“INTO”子句:
SELECT id FROM posts WHERE title LIKE 'problematic value';
我敢打赌,运行后你不会得到任何结果。
解决方案?使用
IFNULL
确保始终从 SELECT ... INTO
返回至少 1 条记录。并使用 IF
语句仅在返回的值被认为有效时运行 UPDATE
。看看:
declare myCursor cursor for select body,id from posts where body like '%Possible Duplicate%' limit 10 offset 11;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
open myCursor;
myloop: loop
fetch myCursor into mybody, myid;
if finished = 1 then leave myloop;
end if;
set Dupdup = 1;
set mytitle = regexp_substr(mybody,'.+?(?=</a>)');
/* IMPORTANT PART */
SELECT IFNULL((select id from posts where title like mytitle), -1)
into Dupdup;
IF Dupdup <> -1 THEN
update posts set dupicateId = Dupdup, isDuplicate = 1 where id = myid;
END IF;
/* --- */
end loop myloop;
close myCursor;
但是也许您有多个列想要选择到多个变量中,然后所有 IFNULL 和子查询都会变得缓慢而混乱。然后,您可以实现一个查询,首先对结果进行计数,并且仅在计数不为 0 时才运行
SELECT ... INTO
:
declare myCursor cursor for select body,id from posts where body like '%Possible Duplicate%' limit 10 offset 11;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
open myCursor;
myloop: loop
fetch myCursor into mybody, myid;
if finished = 1 then leave myloop;
end if;
set Dupdup = 1;
set mytitle = regexp_substr(mybody,'.+?(?=</a>)');
/* IMPORTANT PART */
select COUNT(*) from posts where title like mytitle
into recordsfound;
IF recordsfound <> 0 THEN
select id, col1, col2 from posts where title like mytitle
INTO Dupdup, col1value, col2value;
update posts
set
dupicateId = Dupdup,
col1 = col1value,
col2 = col2value,
isDuplicate = 1
where id = myid;
END IF;
/* --- */
end loop myloop;
close myCursor;
免责声明:我尚未在OP的环境中测试此代码。