【问题标题】:MYSQL Stored Procedure IssuesMYSQL 存储过程问题
【发布时间】:2013-08-07 16:12:40
【问题描述】:

我第一次编写 MySQL 存储过程,我遇到了一个问题 - 我认为是处理程序代码。基本上,我希望这段代码更新pps_users 表中的所有行,但由于某种原因,我在只获取了两行之后就达到了处理程序的“完成条件”。

我用 REPEAT 语法尝试了同样的事情,得到了同样的结果。如果我只是运行游标查询,我正确地得到了我期望的 10,000 条记录,但是当我按原样运行整个事情时,我只在 1 或 2 条记录后点击了完成的代码。

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `changeNFLFavTeams`()
BEGIN
    DECLARE favNFLTeam varchar(100) DEFAULT "";    
    DECLARE favNCAATeam varchar(100) DEFAULT "";    
    DECLARE v_finished INTEGER DEFAULT 0;
    DECLARE user_id bigint(20);
    DECLARE fullNameOfTeam varchar(100) DEFAULT ""; 
    DECLARE update_favs CURSOR FOR select id, favorite_nfl_team from pps_users WHERE favorite_nfl_team is not null;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1;    
    OPEN update_favs;


    updaterecord: LOOP
    FETCH update_favs INTO user_id, favNFLTeam;

        select user_id, favNFLTeam as "Test";

        if v_finished = 1
        then
            select "finished" as "finished";
            LEAVE updaterecord;
        end if;

        select full_name into fullNameOfTeam
                                from teams t 
                                inner join display_names dt on dt.entity_id = t.id 
                                and dt.entity_type = 'teams' 
                                and dt.first_name = favNFLTeam
                                and team_key like 'l.nfl.com%' LIMIT 1;

    select user_id, fullNameOfTeam AS "BeforeUpdate";

            IF fullNameOfTeam != ''
            THEN
               -- here for whatever_transformation_may_be_desired
            -- Find the Full name for the record they chose
                UPDATE pps_users p
                SET favorite_nfl_team = fullNameOfTeam
               WHERE user_id = p.id;
            ELSE
                SELECT 'A' AS 'A'; -- no op
            END IF;  


  end loop updaterecord;

  CLOSE update_favs;

END

【问题讨论】:

  • 在循环的某些迭代中是否可能产生错误?
  • 我在运行它时在输出中看不到任何错误 - 它看起来工作正常。
  • 如果您处理的记录数量较少,问题仍然存在?
  • 是的,我将查询中的 ID 限制为大约 100 个结果,我看到了同样的结果。
  • 尝试逐个测试,先去掉所有body LOOP,证明能正确遍历游标的所有记录。是否可以发布SQL Fiddle 测试用例,尤其是有一些数据?

标签: mysql stored-procedures cursor


【解决方案1】:

这是因为如果您的 SELECT full_name into fullNameOfTeam... 查询不返回任何行,那么它会将 v_finished 设置为 1。显然,这很早就发生了,并强制退出主循环。

关键是要意识到,CONTINUE HANDLER for NOT FOUND 并不单独应用于光标。

您应该使用自己的 CONTINUE 处理程序将辅助查询放入其自己的 BEGIN..END 块中,或者(更简单)在 SELECT full_name 到 fullNameOfTeam... 语句之后设置 v_finished = 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 2014-08-17
    • 1970-01-01
    • 2011-06-16
    • 2016-10-28
    • 2020-03-08
    • 2020-03-09
    • 2015-10-27
    相关资源
    最近更新 更多