Retrieving single value from query

2019-06-21 16:16发布

问题:

I'm attempting to retrieve an integer value from a single table, based on the string field username. I've tried it using a stored proc, and direct text. When I execute the stored proc, I get the proper return value; however, the proper result doesn't come through.

Here are both sets of code - Direct text -

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 query:

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

回答1:

You are not referencing your parameter correctly. If you are adding a parameter named USUsername then in the command text you should use @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;
    }
}

Your stored procedure will also need updating as the parameter name here should also match and you don't need the return variable.

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

You should also look at using the "using" syntax to automatically close your database connections. See Scott Hanselman's example here - http://www.hanselman.com/blog/WhyTheUsingStatementIsBetterThanASharpStickInTheEyeAndASqlConnectionRefactoringExample.aspx



回答2:

I dont know how you called your stored procedure, but theres a bug in the query that you posted:

"SELECT USRole FROM tblUser WHERE USUsername = CUSER"

should be replaced with

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


You are currently not really making the parameter part of the query, but trying to find the value CUSER within the column



回答3:

Instead of using the return value of the stored procedure (RETURN @USRole), send the results back using a Select statement (e.g. Select @USRole). What is going on is that the return value of a stored procedure isn't the same as what is used by ExecuteScalar. ExecuteScalar returns the first column and row of the output. The return value is different and must accessed using the specially named parameter @RETURN_VALUE or the special ParameterDirection.ReturnValue property.

A revised version of your procedure would look like:

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



回答4:

Use parameter correctly. And dont forget to close connection on finally statement.

 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:

If you insist on using the return value you can do it by setting the Parameter direction and using ExecuteNonQuery

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

If you want to use ExecuteScalar then just change your proc to select the variable instead of Return

You should note that what you put in for the parameter name is arbitrary.