0

我正在使用数据库Stored Procedures中的登录身份验证。MySQL下面是我写的代码,但它不起作用。让我知道,有什么问题。

我有以下问题

  1. 如何检查,CURSORemptynull
  2. 有什么办法,我们写程序。

我在做什么..

  1. 取两个input参数和两个参数ouput

  2. 检查用户或密码是否无效,将这些值存储在 OUT 参数中 SELECT 'Invalid username and password', 'null' INTO oMessage, oUserID;

  3. 如果用户和密码有效,但 列 isActive0SELECT 'Inactive account', 'null' INTO oMessage, oUserID;

  4. 如果成功, SELECT 'Success', v_UserID INTO oMessage, oUserID;

SQL 代码

DELIMITER $$

USE `acl`$$


CREATE
    DEFINER = `FreeUser`@`localhost` 
    PROCEDURE `acl`.`checkAuthenticationTwo`(
    IN iUsername VARCHAR(50),
    IN iPassword VARCHAR(50),
    OUT oMessage VARCHAR(50),
    OUT oUserID INT
    )

    BEGIN
    DECLARE v_isActive INT;
    DECLARE v_UserID INT;
    DECLARE v_count INT;
    DECLARE cur1 CURSOR FOR SELECT UserID, IsActive FROM m_users WHERE (LoginName = TRIM(iUsername) OR Email = TRIM(iUsername)) AND `Password` = iPassword;

    OPEN cur1;
    SET v_count = (SELECT FOUND_ROWS());

    IF (v_count > 0)

        FETCH cur1 INTO v_UserID, v_isActive;

        IF (v_isActive = 0) THEN
            SELECT 'Inactive account', 'null' INTO oMessage, oUserID;
        ELSE
            SELECT 'Success', v_UserID INTO oMessage, oUserID;
        END IF;

    ELSE
        SELECT 'Invalid username and password', 'null' INTO oMessage, oUserID;
    END IF;


    END$$

DELIMITER ;
4

1 回答 1

3

你绝对不需要CURSORs ;使用简单的SELECT. 更简洁的 SP 版本可能看起来像

DELIMITER $$
CREATE DEFINER = `FreeUser`@`localhost` PROCEDURE `acl`.`checkAuthenticationTwo`
(
    IN iUsername VARCHAR(50),
    IN iPassword VARCHAR(50),
    OUT oMessage VARCHAR(50),
    OUT oUserID INT
)
BEGIN
    SELECT CASE WHEN IsActive = 0 THEN 'Inactive account' ELSE 'Success' END,
           CASE WHEN IsActive = 0 THEN NULL ELSE UserID END 
      INTO oMessage, oUserID
      FROM m_users 
     WHERE (LoginName = TRIM(iUsername) 
           OR Email = TRIM(iUsername)) 
       AND `Password` = iPassword
     LIMIT 1; -- you better protect yourself from duplicates
    SET oMessage = IFNULL(oMessage, 'Invalid username and password');
END$$
DELIMITER ;

它的作用是尝试选择用户名或电子邮件等于 iUsername 且密码等于 iPassword 的行,并将两个值输出到输出变量。一路上它CASE用来查看 isActive 值。如果是,0则将消息设置为“非活动”,并将用户 ID 设置为 NULL。否则,它会返回“成功”消息和已找到的真实用户 ID。现在,如果未找到用户,则两个变量都将设置为 NULL。我们可以利用它并使用IFNULL()函数来检测该事实并将消息设置为“无效的用户名和密码”。

这是SQLFiddle演示 我个人会更进一步并简化它,并使其成为具有以下接口的单语句 SP:

回报:
   如果找到具有用户名和密码的用户,则用户 ID(大于 0)
   0 - 用户名和(或)密码不正确
  -1 - 用户处于非活动状态

这个想法是表示层的任务是为用户生成适当的消息,而不是将所有这些消息文字分散在数据层中。

CREATE DEFINER = `FreeUser`@`localhost` PROCEDURE `acl`.`checkAuthenticationThree`
(
  IN iUsername VARCHAR(50),
  IN iPassword VARCHAR(50),
  OUT oUserID INT
)
  SET oUserID = IFNULL(
  (
    SELECT CASE WHEN IsActive = 0 THEN -1 ELSE UserID END
      FROM m_users 
     WHERE (LoginName = TRIM(iUsername) 
           OR Email = TRIM(iUsername)) 
       AND `Password` = iPassword
     LIMIT 1 -- you better protect yourself from duplicates
  ), 0);

这是SQLFiddle演示

于 2013-06-21T09:44:42.783 回答