MySQL 光标在到达末尾之前跳出

问题描述 投票:0回答:1

这是我的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
就会被执行。我想不出其他原因了

有办法解决这个问题吗?

mysql sql procedure sql-function
1个回答
0
投票

我遇到了类似的问题,这是由于循环内的

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的环境中测试此代码。

© www.soinside.com 2019 - 2024. All rights reserved.