0

単純なユーザー ログイン機能のストアド プロシージャを作成しました。

USE [project]
GO
/****** Object:  StoredProcedure [dbo].[authenticateLogin]    Script Date: 10/18/2013     9:24:57 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[authenticateLogin] @userName varchar, @password varchar
AS
BEGIN
    Declare @userRole int;
    Declare @uPassword varchar;
        Declare @uRole int;

    SET @uPassword = (SELECT uPassword FROM [user] WHERE uName=@userName); 

IF(@uPassword = @password)
    SET @userRole = (SELECT uRole FROM [user] WHERE uName=@userName); 
ELSE
    SET @userRole = 0;
--RETURN @userRole
SELECT @userRole 
END

そして、私はこれを私のプログラムから次のように呼び出しています:

internal int Authenticate(string userName, string password)
    {
        int userRole = 0;
        Shared shrObj=new Shared();
        string encPassword = shrObj.EncryptToString(password);
        SqlConnection sqlCon = Shared.GetSqlCon();

        var sqlCom = new SqlCommand("authenticateLogin", sqlCon);
        sqlCom.CommandType = CommandType.StoredProcedure;           

        sqlCom.Parameters.AddWithValue("@userName", userName);
        sqlCom.Parameters.AddWithValue("@password", encPassword);
        try
        {
            userRole = Shared.ExecuteNonQueryOnProcedure(sqlCon, sqlCom);
            if (userRole > 0) return userRole;
        }
        catch (SqlException sqlEx)
        {
            //catch
        }

        finally
        {
            Shared.COC(sqlCon);
        }
        return userRole;
    }

Shared.cs

public static int ExecuteNonQueryOnProcedure(SqlConnection sqlCon, SqlCommand sqlCom) {

        int rowCount = 0;
        SqlParameter returnParameter = sqlCom.Parameters.Add("userRole", SqlDbType.Int);
        returnParameter.Direction = ParameterDirection.ReturnValue;

        try
        {
            sqlCon.Open();
            //rowCount = sqlCom.ExecuteNonQuery();
            var inu = sqlCom.ExecuteScalar().ToString();
        }
        catch (Exception ex)
        {
            //catch
            return rowCount;
        }
        return (int)returnParameter.Value;
    }

しかし、問題は、提供された引数が一致する場合でも、常に 0 を返すことです。どこが間違っているのか教えてください。

4

4 に答える 4

2

EXEC procedureSqlCommand で渡す必要はありません。CommandType.StoredProcedureを使用する

var sqlCom = new SqlCommand("authenticateLogin",sqlCon);
sqlComm.CommandType = CommandType.StoredProcedure; //here
sqlCom.Parameters.AddWithValue("@userName", userName);
sqlCom.Parameters.AddWithValue("@password", encPassword);

try
{
    userRole = (short)sqlComm.ExecuteScalar();
    if (userRole > 0) return userRole;
}

戻り値を取得するには、次のようなパラメーターを追加できます。

SqlParameter returnParameter = sqlCom.Parameters.Add("userRole", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
sqlCom.ExecuteScalar();
int returnValue = (int) returnParameter.Value;
于 2013-10-18T16:43:30.607 に答える
1

そのような SP から値を返すことはありません。実際、戻り値はあまり役に立ちません。

そのような認証に SP を使用する場合は、次のようなものが機能します。

CREATE PROCEDURE [dbo].[authenticateLogin] @userName varchar, @password varchar
AS
BEGIN
SELECT uRole FROM [User] 
WHERE uName=@userName AND uPassword = @password 

これにより、一致するユーザー名とパスワードを持つすべてのユーザーの uRole フィールドが返されます。これは、1 行または 0 行であることが期待されます。

于 2013-10-18T16:48:00.237 に答える
1

あなたのSQLではあなたが持つべきです

SELECT @userRole 

それ以外の

RETURN @userRole

ExecuteScalar()はコマンドを実行し、戻り値ではなく、SQL コマンドが生成する最初の行の最初の列の値を返します。

于 2013-10-18T16:44:38.850 に答える
0

わかりましたみんな、それがうまくいったのは、私も他の誰も気づかなかった愚かな間違いでした.

文字の値を指定していなかったvarchar(?)ため、すべての変数の最初の文字のみを取得していたため、if-Elseブロックが失敗していました。それを修正し、今はすべて問題ありません。

助けてくれてありがとう。:)

于 2013-10-18T22:13:19.613 に答える