【问题标题】:Retrieving single value from query从查询中检索单个值
【发布时间】:2012-06-04 22:09:45
【问题描述】:

我正在尝试根据字符串字段用户名从单个表中检索整数值。我已经尝试过使用存储过程和直接文本。当我执行存储过程时,我得到了正确的返回值;然而,正确的结果并没有出现。

这是两套代码 - 直接文本 -

public int GetUserRole(string CUSER)
{
    try
    {
        SQLCON = new SqlConnection(connectionString);
        SQLCON.Open();
        SQLCommand = new SqlCommand();
        SQLCommand.CommandType = CommandType.Text;
        SQLCommand.Parameters.Add("USUsername", SqlDbType.VarChar).Value = CUSER;
        SQLCommand.CommandText = "SELECT USRole FROM tblUser WHERE USUsername = CUSER";
        Int32 USRole = (Int32) SQLCommand.ExecuteScalar();

        return USRole;

    }
    catch
    {
        HttpContext.Current.Response.Redirect("~/ErrorRedirect.aspx", false);
        return 0;
    }
}

SQL 查询:

ALTER PROCEDURE [dbo].[spGetUserRole]
-- Add the parameters for the stored procedure here
    @username VARCHAR(50)
AS
BEGIN
-- Declare the return variable here
DECLARE @USRole as int

-- Add the T-SQL statements to compute the return value here
SELECT @USRole = tblUser.USRole FROM tblUser WHERE USUsername = @username

-- Return the result of the function
RETURN @USRole  
END

【问题讨论】:

    标签: c# sql sql-server tsql ado.net


    【解决方案1】:

    您没有正确引用您的参数。如果您要添加一个名为 USUsername 的参数,那么在命令文本中您应该使用 @USUsername:

    public int GetUserRole(string CUSER)
    {
        try
        {
            SQLCON = new SqlConnection(connectionString);
            SQLCON.Open();
            SQLCommand = new SqlCommand();
            SQLCommand.CommandType = CommandType.Text;
            SQLCommand.Parameters.Add("USUsername", SqlDbType.VarChar).Value = CUSER;
            SQLCommand.CommandText = "SELECT USRole FROM tblUser WHERE USUsername = @USUsername";
            Int32 USRole = (Int32) SQLCommand.ExecuteScalar();
    
            return USRole;
    
        }
        catch (Exception)
        {
            HttpContext.Current.Response.Redirect("~/ErrorRedirect.aspx", false);
            return 0;
        }
    }
    

    您的存储过程也需要更新,因为这里的参数名称也应该匹配,并且您不需要返回变量。

    ALTER PROCEDURE [dbo].[spGetUserRole]
    -- Add the parameters for the stored procedure here
    @USUsername VARCHAR(50)
    
    AS
    BEGIN
    
    -- Add the T-SQL statements to compute the return value here
    SELECT tblUser.USRole FROM tblUser WHERE USUsername = @USUsername
    
    END
    

    您还应该考虑使用“使用”语法自动关闭数据库连接。在此处查看 Scott Hanselman 的示例 - http://www.hanselman.com/blog/WhyTheUsingStatementIsBetterThanASharpStickInTheEyeAndASqlConnectionRefactoringExample.aspx

    【讨论】:

    • Int32 USRole = (Int32) SQLCommand.ExecuteScalar();如果有零个记录会在该行上爆炸,那么你不是处理错误,而是使用通用的 catch all Exception 吞入你的 catch 并返回 0
    • 我想你错过了SQLCommand.Connection = SQLCON 并关闭了连接?
    【解决方案2】:

    我不知道您是如何调用存储过程的,但是您发布的查询中有一个错误:

    "SELECT USRole FROM tblUser WHERE USUsername = CUSER"
    

    应该替换为

    SQLCommand.Parameters.Add("@USUsername", SqlDbType.VarChar).Value = CUSER;
    "SELECT USRole FROM tblUser WHERE USUsername = @USUsername"
    


    您目前并没有真正将参数作为查询的一部分,而是试图在列中找到值 CUSER

    【讨论】:

      【解决方案3】:

      不要使用存储过程的返回值 (RETURN @USRole),而是使用 Select 语句(例如 Select @USRole)将结果发回。发生的事情是存储过程的返回值与 ExecuteScalar 使用的不同。 ExecuteScalar 返回输出的第一列和第一行。返回值不同,必须使用特殊命名的参数@RETURN_VALUE 或特殊的ParameterDirection.ReturnValue 属性访问。

      您的程序的修订版本如下所示:

      ALTER PROCEDURE [dbo].[spGetUserRole]
      -- Add the parameters for the stored procedure here
      @USUsername VARCHAR(50)
      
      AS
      BEGIN
      
      -- Add the T-SQL statements to compute the return value here
      Select tblUser.USRole 
      FROM tblUser 
      WHERE USUsername = @USUsername
      
      END
      

      RETURN (Transact-SQL)

      SqlCommand.ExecuteScalar Method

      【讨论】:

      • 谢谢。这么简单的事情却造成了这么多的恶化。非常感谢!
      • @Thomas。仅当您从服务器(例如SqlCommandBuilder.DeriveParameters(cmd);。否则ParameterDirection.ReturnValue 才是最重要的,名称是任意的
      【解决方案4】:

      正确使用参数。并且不要忘记在 finally 语句上关闭连接。

       public int GetUserRole(string CUSER)
          {
              try
              {
                  SQLCON = new SqlConnection(connectionString);
                  SQLCON.Open();
                  SQLCommand = new SqlCommand();
                  SQLCommand.CommandType = CommandType.Text;
                  SQLCommand.CommandText = "SELECT USRole FROM tblUser WHERE USUsername = @USUsername  ";
                  SQLCommand.Parameters.Add("USUsername", SqlDbType.VarChar).Value = CUSER;
      
                  Int32 USRole = (Int32) SQLCommand.ExecuteScalar();
      
                  return USRole;
      
              }
              catch (Exception)
              {
                  HttpContext.Current.Response.Redirect("~/ErrorRedirect.aspx", false);
                  return 0;
              }
              finally { close connection here.. }
      
          }
      

      【讨论】:

        【解决方案5】:

        如果你坚持使用返回值,你可以通过设置参数方向并使用ExecuteNonQuery来做到这一点

        SqlParameter p = cmd.Parameters.Add("@USRole", SqlDbType.Int);
        p.Direction = ParameterDirection.ReturnValue;
        cmd.ExecuteNonQuery(); 
        int returnvalue = (int)cmd.Parameters["@USRole"].Value;
        

        如果您想使用 ExecuteScalar,那么只需将您的 proc 更改为 select 变量而不是 Return

        您应该注意,您为参数名称输入的内容是任意的。

        【讨论】:

          猜你喜欢
          • 2018-05-26
          • 2014-05-02
          • 1970-01-01
          • 2020-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多