0

データベースでログイン認証を行っStored ProceduresていMySQLます。以下はコードですが、私が書いたものですが、動作しません。何が悪いのか教えてください。

以下の質問があります

  1. かどうかを確認するCURSOR方法emptynull
  2. 方法はありますか、手順を書きます。

私がしていること..

  1. inputの 2 つのパラメーターと 2つのパラメーターを取りますouput

  2. ユーザーまたはパスワードが有効でないかどうかを確認し、それらの値を OUT パラメータに保存しました SELECT 'Invalid username and password', 'null' INTO oMessage, oUserID;

  3. ユーザーとパスワードが有効であるが、isActive列が次の0 場合 SELECT '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

CURSORそのために sは絶対に必要ありません。無地シンプルを使用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 に等しい行を選択しようとし、出力変数に 2 つの値を出力します。途中CASEで isActive 値を調べます。その場合0、メッセージを「非アクティブ」に設定し、ユーザー ID を NULL に設定します。それ以外の場合は、「成功」メッセージと見つかった実際のユーザー ID が返されます。現在、ユーザーが見つからない場合、両方の変数が NULL に設定されます。それを活用し、IFNULL()関数を使用してその事実を検出し、メッセージを「無効なユーザー名とパスワード」に設定できます。

これがSQLFiddleのデモです。個人的には、さらに進んでもう少し単純化し、次のインターフェースを備えた1ステートメントのSPにします。

戻り値:
   userid (> 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 に答える