4

我正在尝试了解 MySQL 存储过程,我想检查用户登录凭据是否有效,如果有效,请更新用户在线状态:

-- DROP PROCEDURE IF EXISTS checkUser;
DELIMITER //
CREATE PROCEDURE checkUser(IN in_email VARCHAR(80), IN in_password VARCHAR(50))
BEGIN
    SELECT id, name FROM users WHERE email = in_email AND password = in_password LIMIT 1;
    -- If result is 1, UPDATE users SET online = 1 WHERE id = "result_id";
END //
DELIMITER ;

如何根据结果集的行数 == 1 或 id IS NOT NULL 来制作这个 if 语句?

4

3 回答 3

8
DELIMITER //
CREATE PROCEDURE checkUser(IN in_email VARCHAR(80), IN in_password VARCHAR(50))
BEGIN
    DECLARE tempId INT DEFAULT 0;
    DECLARE tempName VARCHAR(50) DEFAULT NULL;
    DECLARE done INT DEFAULT 0;

    DECLARE cur CURSOR FOR 
        SELECT id, name FROM users WHERE email = in_email AND password = in_password;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur;

    REPEAT
        FETCH cur INTO tempId, tempName;
        UPDATE users SET online = 1 WHERE id = tempId;
    UNTIL done  = 1 END REPEAT;
    CLOSE cur;

    SELECT tempName;
END //
DELIMITER ;

注意:我没有测试过这个。MySQL 可能不喜欢对它当前打开游标的表进行 UPDATE。

PS:您应该重新考虑如何存储密码


重新评论RETURNvs. OUTvs. 结果集:

RETURN仅用于存储函数,不用于存储过程。当您想在另一个 SQL 表达式中调用例程时,使用存储函数。

SELECT LCASE( checkUserFunc(?, ?) );

您可以使用OUT参数,但您必须先声明一个用户变量才能作为该参数传递。然后你必须选择那个用户变量来获取它的值。

SET @outparam = null;
CALL checkUser(?, ?, @outparam);
SELECT @outparam;

从存储过程返回结果集时,最容易使用SELECT查询。

于 2009-12-14T20:39:02.377 回答
2

采用:

UPDATE USERS
   SET online = 1
 WHERE EXISTS(SELECT NULL
                FROM USERS t
               WHERE t.email = IN_EMAIL
                 AND t.password = IN_PASSWORD
                 AND t.id = id)
   AND id = 'result_id'

为什么你LIMIT 1的 SELECT 上有?您真的希望电子邮件和密码不止一次出现在数据库中吗?

于 2009-12-14T20:21:17.020 回答
0

如果您的结果返回 1,您可以尝试使用 if 语句查询哪里只能存在一个电子邮件地址?像这样的东西

update users set if(result==1,online=1,online=0) where email=emailadress
于 2009-12-14T20:26:44.917 回答