Mysql 存储过程转到无限循环

Mysql 存储过程转到无限循环,mysql,Mysql,我制作一个存储过程是为了检查用户是否存在。问题是,每当我传递正确的用户名时,它都会成功执行,但当我传递错误的用户名时,它会经历一个无限循环 我哪里做错了?以下是我的存储过程: CREATE PROCEDURE `VerifyUserNPass`(userParam varchar(50), out result int) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE tempUser varchar(50) default '';

我制作一个存储过程是为了检查用户是否存在。问题是,每当我传递正确的用户名时,它都会成功执行,但当我传递错误的用户名时,它会经历一个无限循环

我哪里做错了?以下是我的存储过程:

CREATE PROCEDURE `VerifyUserNPass`(userParam varchar(50), out result int)
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE tempUser varchar(50) default '';
    DECLARE count int default 0;
    DECLARE noRows int;

    DECLARE userList cursor for select userName from users;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    select count(*) into noRows from users;

    OPEN userList;
    read_loop: LOOP
        FETCH userList into tempUser;
        IF tempUser = userParam THEN
                SET @count = count + 1;
                LEAVE read_loop;
        ELSEIF count > noRows THEN
                LEAVE read_loop;
        END IF;

    END LOOP;
    CLOSE userList;

    select count into result;

END

确保为所有分支增加循环计数器,而不仅仅是在succes分支中,并使用result变量保存结果

DECLARE userFound int default 0;
......
read_loop: LOOP
    FETCH userList into tempUser;
    SET @count = @count + 1;
    IF tempUser = userParam THEN
           SET @userFound = 1
           LEAVE read_loop;
    ELSEIF count > noRows THEN
            LEAVE read_loop;
    END IF;
    .....
    select userFound into result;
我希望这将返回相同的结果(但我不是


确保为所有分支增加循环计数器,而不仅仅是在succes分支中,并使用result变量保存结果

DECLARE userFound int default 0;
......
read_loop: LOOP
    FETCH userList into tempUser;
    SET @count = @count + 1;
    IF tempUser = userParam THEN
           SET @userFound = 1
           LEAVE read_loop;
    ELSEIF count > noRows THEN
            LEAVE read_loop;
    END IF;
    .....
    select userFound into result;
我希望这将返回相同的结果(但我不是


要修复代码,请对
done
变量使用条件测试来确定是否退出循环。(当不再有行时,
done
变量初始化为FALSE,然后在CONTINUE处理程序中设置为TRUE。)

去掉查询“
count(*)
”查询和
noRows
变量;这些是不需要的。(在并发系统中,count(*)查询返回的值可能与稍后查询返回的行数不同。(请考虑在您的过程运行时,其他会话可能插入或删除行。)


另外,还要去掉对
@count
用户变量的引用。用户变量
@coount
和过程变量
count
的引用是混合的。这些都是独立变量。过程不需要使用用户变量。相反,请坚持使用中声明的变量您的过程。(保存用户变量以备需要时使用。)


一种更有效的编码方法是,通过在查询中添加WHERE子句,让数据库找到您感兴趣的行(不需要获取与您感兴趣的条件不匹配的行)

修改光标定义以包含谓词(即WHERE子句中的条件),以限制返回的行:

DECLARE userList cursor for select userName from users
  WHERE userName = userParam LIMIT 1;

我不明白这里是否需要一个过程。一个原生SQL语句会更有效率,例如

SELECT 1 AS found FROM users u WHERE u.userName = 'foo' LIMIT 1;

要修复代码,请对
done
变量使用条件测试来确定是否离开循环。(当不再有行时,
done
变量初始化为FALSE,然后在CONTINUE处理程序中设置为TRUE。)

去掉查询“
count(*)
”和
noRows
变量;这些都是不需要的。(在并发系统中,count(*)查询可能返回一个不同于后续查询返回的行数的值。(请考虑在您的过程运行时,其他会话可以插入或删除行。)


另外,还要去掉对
@count
用户变量的引用。用户变量
@coount
和过程变量
count
的引用是混合的。这些都是独立变量。过程不需要使用用户变量。相反,请坚持使用中声明的变量您的过程。(保存用户变量以备需要时使用。)


一种更有效的编码方法是,通过在查询中添加WHERE子句,让数据库找到您感兴趣的行(不需要获取与您感兴趣的条件不匹配的行)

修改光标定义以包含谓词(即WHERE子句中的条件),以限制返回的行:

DECLARE userList cursor for select userName from users
  WHERE userName = userParam LIMIT 1;

我不明白这里是否需要一个过程。一个原生SQL语句会更有效率,例如

SELECT 1 AS found FROM users u WHERE u.userName = 'foo' LIMIT 1;

我认为COUNT变量返回的结果是1=true(存在)和0=false(不存在)?是的。我只回答了这个问题,但它肯定有更多的问题:-)嘿,也许你是对的?我只是猜测,因为代码块的格式不正确。我认为COUNT变量返回的结果是1=true(存在)和0=false(不存在)?是的。我只回答了这个问题,但它肯定有更多的问题:-)嘿,也许你是对的?我只是猜测,因为代码块的格式不好。你对用户变量的引用混合在一起(
@count
)和过程变量
count
。不需要
noRows
变量,也不需要对其进行任何测试。使用
done
变量来确定是否已处理所有行,而不是运行单独的查询来获取行数。在查询中包含WHERE子句以仅返回ro将更有效ws,其中用户名与userParam的值匹配。您混合引用了用户变量(
@count
)和过程变量
count
。不需要
noRows
变量,也不需要对其进行任何测试。使用
done
变量来确定是否已处理所有行,而不是运行单独的查询来获取行数。在查询中包含WHERE子句以仅返回ro将更有效ws,其中用户名与userParam的值匹配。