views:

69

answers:

3

I have a stored procedure that is called to validate a user during login. If success it returns the user entity, and that works good! My question is if it doesn't work, I'll raise an error in the SP, How do I catch this error and use it in the best way? Right now I'm getting nullrefference, this is the code: Store procedure:

ALTER PROCEDURE getEmployee
    (
    @username nvarchar(50),
    @password nvarchar(50)
    )
AS
DECLARE @Error_MSG nvarchar(50)
BEGIN

IF EXISTS (select * from Employee where eUsername = @username AND pword = @password)
begin
    select * from Employee where eUsername = @username AND pword = @password

    END

    ELSE
    BEGIN
    SET @Error_MSG = 'Wrong password, or user doesnt exist'
    RAISERROR (@Error_MSG, 11,1)
    END
END

And in the code it looks like this, the SP is getEmployee

ActivityDatabaseDataContext dc = new ActivityDatabaseDataContext();
        Employee emp;
        public bool logIn(string piUsername, string piPassword)
        {
            try
            {
                emp = dc.getEmployee(piUsername, piPassword).Single();
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message + ex.InnerException.Message;
            }
            if (emp != null)
            {
                AppHelper.AppHelper.setUser(emp);
                return true;
            }
            else
            {
                return false;
            }

My question is how I should handle the exception?

+1  A: 

Your InnerException is probably null.

You should try to catch and deal with specific exceptions, in this case SqlExceptions.

Noel Abrahams
+4  A: 

I wouldn't generally raise an error from a SP unless it was actually a system problem with the operation. Entering the wrong username and password is a user problem, and one you need only deal with at the interface level, so I'd throw most of that SP away and deal with the two use cases (1 row or 0 rows returned) in the business layer or interface code. If 0 rows, throw up the "Wrong username or password" message to the client and if 1, log in.

ALTER PROCEDURE getEmployee 
( 
    @username nvarchar(50), 
    @password nvarchar(50) 
) 
AS
BEGIN
    select * from Employee where eUsername = @username AND pword = @password
END
Kendrick
Agreed! This is not really an "error" and it certainly shouldn't be raised from the database.
Chris Conway
Yes, you are right, it's not an error, so I should change it, but how should I then wright the SP, I still want to return the full entity from the db if success, but let's say 0 if nothing, how should I change my SP? /Thanks
Fore
From the above proc, you should be able to examine the returned value to see how many items it contains. If it's an empty set, you know there's an issue with the username/password. If it has 1 item in it, they're good to log in, and if there are more than one items (assuming you feel the OCD need to check, since the DB should ensure this case) then there's a serious problem :-)
Kendrick
hehe, true that! Thanks for the help, To make it clear, if someone reads this later, I now removed the RAISERROR from my SP, and now only select * , and in my code I did I count as follows: var getemp = dc.getEmployee1(piUsername, piPassword); if (getemp.Count() > 0) { AppHelper.AppHelper.setUser(emp); return true; } else { return false; }
Fore
A: 
   ALTER PROCEDURE getEmployee
        (
        @username nvarchar(50),
        @password nvarchar(50)
        )
    AS
    BEGIN

    select * from Employee where eUsername = @username AND pword = @password

    END

...

SqlCommand cmd = new SqlCommand("getEmployee", conn);
cmd.AddWithValue('@username', name);
cmd.AddWithValue('@password', pass);

SqlAdapter da = new SqlAdapter(cmd);
DataSet ds= new DataSet();
da.Fill(ds);

if (ds.Table.Count > 0 && ds.Table.Rows.Count == 1)  {
    // success
} else {
    // fail
}
signetro
Just a note: The "top 1" is redundant if eUsername is unique (and it should be) in a column that does not allow duplicates. An alternate way of looking at it: If the column is not constrained and there are more than 1 row returned, then this truly is a system error.
Kendrick
You are right about top and the other things.
signetro