【问题标题】:C# Stored Procedure Return ScalarC# 存储过程返回标量
【发布时间】:2021-09-04 03:00:16
【问题描述】:

我有一个将返回 1 或 0 的存储过程。我似乎无法将它正确地包装在 C# 函数中。任何帮助表示赞赏。

这是我的存储过程(我已经在 SQL Server 中测试过并且可以正常工作):

CREATE PROCEDURE VerifyAccount
    @Email VARCHAR(50),
    @Pass VARCHAR(100)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Salt CHAR(25);
    DECLARE @PwdWithSalt VARCHAR(125);
    DECLARE @PwdHash VARBINARY(20);  

    SELECT @Salt = Salt, @PwdHash = Pass 
    FROM users 
    WHERE EMAIL = @Email;

    SET @PwdWithSalt = @Salt + @Pass;

    IF (HASHBYTES('SHA1', @PwdWithSalt) = @PwdHash)
        RETURN 1;
    ELSE
        RETURN 0;
END;

如果我打开一个新的 SQL 查询并运行这段代码,它就可以工作:

DECLARE @Result INT;

EXEC @Result = VerifyAccount 
                   @Email = 'myemail@email.com', @Pass = 'Str0ngP@ssw0rd!';
SELECT @Result;

当我尝试将它包装在 C# 代码中时,它会返回一个 -1 值,这在此过程中是不可能的。它应该返回一个“1”。我做错了什么?

public static int ValidateUser(User user)
{
    int result = 0;
    
    using (SqlConnection conn = new SqlConnection(SQLQuery.connDb))
    {
        using (var command = new SqlCommand("VerifyAccount", conn)
        {
            CommandType = CommandType.StoredProcedure,
            Parameters =
            {
                new SqlParameter("@Email", user.Email),
                new SqlParameter("@Pass", user.Password)
            }
        })
        {
            try
            {
                conn.Open();
                result = command.ExecuteNonQuery();
                conn.Close();
            }
            catch (Exception e)
            {
                result = -15;
                Console.WriteLine(e.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }
        }
    }

    return result;
 }

【问题讨论】:

  • 使用执行缩放器而不是执行非查询。 command.ExecuteNonQuery() 返回受影响的行数。由于您必须选择单个值,因此只能使用 command.ExecuteSCaler。
  • 存储过程返回值的约定是指示成功或失败,而不是提供“数据”。通过网络传递纯文本密码也是一个坏主意,而且非常不安全。 SHA1 也已被弃用。至少您不存储密码 - 但您通过存储盐来构成安全性。

标签: c# sql-server stored-procedures


【解决方案1】:

这里是你如何读取存储过程的返回值。

public static int ValidateUser(User user)
{
    int result = 0;
    
    using (SqlConnection conn = new SqlConnection(SQLQuery.connDb))
    {
        using (var command = new SqlCommand("VerifyAccount", conn)
        {
            CommandType = CommandType.StoredProcedure,
            Parameters =
            {
                new SqlParameter("@Email", user.Email),
                new SqlParameter("@Pass", user.Password)
            }
        })
        {
            try
            {
            
                // STEP 01: **** SETUP UP RETURN VALUE STORED PROCEDURES *****
                var returnParameter = command.Parameters.Add("@ReturnVal", SqlDbType.Int);
                returnParameter.Direction = ParameterDirection.ReturnValue;
                
                conn.Open();
                result = command.ExecuteNonQuery();
                
                // STEP 02: **** READ RETURN VALUE *****
                var result = returnParameter.Value;
                
                conn.Close();
            }
            catch (Exception e)
            {
                result = -15;
                Console.WriteLine(e.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }
        }
    }
    return result;
 }
 
 

【讨论】:

    【解决方案2】:

    ExecuteNonQuery 返回受影响的行数

    你需要

      result =  (int)command.ExecuteScalar();
    

    【讨论】:

      猜你喜欢
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 2010-12-18
      • 2014-04-18
      相关资源
      最近更新 更多