This is my procedure:
DECLARE @ReturnValue int
SELECT @ReturnValue = idUser
FROM Users
WHERE Alias = @UserAlias AND Password = @UserPassword
RETURN @ReturnValue
This is my C# code where I'd hope I could retrieve the value from the procedure:
TeamPWSecureBD.Open(); //Open SQL Connection
string alias = textBoxUsernameLogin.Text.Trim();
string pass = textBoxPasswordLogin.Text;
SqlCommand LoginVerify = new SqlCommand("_spUserVerify", TeamPWSecureBD);
LoginVerify.CommandType = CommandType.StoredProcedure;
LoginVerify.Parameters.AddWithValue("@UserAlias", alias);
LoginVerify.Parameters.AddWithValue("@UserPassword", pass);
SqlDataReader UserVerify = LoginVerify.ExecuteReader();
//Se o valor retornado pelo sp for 0 significa que o user não existe.
//O sp retorna o id do utilizador se o username e a password estiverem corretas.
//O id de utilizador menor é o 7.
if (Convert.ToInt32(UserVerify.GetSqlValue(0)) == 0)
MessageBox.Show("Invalid username/password.", "Login Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
else
{
GlobalVariables.UserLoggedIn = Convert.ToInt32(UserVerify.GetSqlValue(0));
PWLists MainForm = new PWLists();
MainForm.ShowDialog();
this.Close();
}
When I execute the procedure in SQL Server, the returned value is correct.
But once I try to read it in the form it crashes with error:
invalid attempt to read when no data is present
If you want to catch the value of the RETURN statement executed by your stored proceduere you need to add another parameter to your SqlCommand
SqlParameter r = LoginVerify.Parameters.Add("@return", SqlDbType.Int);
r.Direction = ParameterDirection.ReturnValue;
r.Value = 0;
SqlDataReader UserVerify = LoginVerify.ExecuteReader();
// Now you need to complete the reading from the UserVerify reader and
// finally you can catch the return value
.....
UserVerify.Close();
int result = (int)r.Value;
However, given the code of your StoredProcedure, I think you could simply avoid to declare another parameter and also the SqlDataReader because you seem to return just one row with one field. The exact scope for ExecuteScalar...
SP is now just a select
SELECT idUser FROM Users
WHERE Alias = @UserAlias AND Password = @UserPassword
and the code to retrieve the idUser
is
object result = LoginVerify.ExecuteScalar();
if (result == null)
MessageBox.Show("Invalid username/password.", "Login Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
else
{
GlobalVariables.UserLoggedIn = Convert.ToInt32(result);
PWLists MainForm = new PWLists();
MainForm.ShowDialog();
this.Close();
}