2010-10-21 55 views
3

我有一個存儲過程被調用來在登錄過程中驗證用戶。 如果成功,它將返回用戶實體,而且效果很好!我的問題是如果它不起作用,我會在SP中提出一個錯誤,我如何捕獲這個錯誤並以最好的方式使用它?現在我越來越nullrefference,這是代碼: 存儲過程:從C#中的存儲過程中捕捉錯誤#

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 

而且在它看起來像這樣的代碼中,SP是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; 
      } 

我的問題是我應該怎麼處理異常?

回答

4

我通常不會從SP引發錯誤,除非它實際上是操作的系統問題。輸入錯誤的用戶名和密碼是一個用戶問題,並且只需要在界面級別處理,所以我會拋棄大部分SP並處理這兩個用例(1行或0行返回)業務層或接口代碼。如果0行,丟了 「錯誤的用戶名或密碼」 消息給客戶端,如果1,登錄。

ALTER PROCEDURE getEmployee 
( 
    @username nvarchar(50), 
    @password nvarchar(50) 
) 
AS 
BEGIN 
    select * from Employee where eUsername = @username AND pword = @password 
END 
+0

同意!這不是一個真正的「錯誤」,它肯定不應該從數據庫中提出。 – 2010-10-21 17:50:37

+0

是的,你是對的,這不是一個錯誤,所以我應該改變它,但我應該怎麼樣才能保證SP,如果成功,我仍然想從數據庫中返回完整的實體,但如果沒有,我們應該說0我改變我的SP? /謝謝 – Fore 2010-10-21 19:13:58

+0

從上面的過程中,你應該能夠檢查返回的值,看看它包含了多少項。如果它是空集,則知道用戶名/密碼存在問題。如果它有一個項目,他們很好登錄,如果有多個項目(假設你覺得強迫症需要檢查,因爲數據庫應該確保這種情況),那麼存在一個嚴重的問題:-) – Kendrick 2010-10-21 19:26:32

1

你的InnerException可能爲null。

您應該嘗試捕捉並處理特定的例外情況,在這種情況下爲SqlExceptions

1
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 
} 
+0

請注意:如果eUsername在不允許重複的列中唯一(並且應該是),那麼「top 1」是多餘的。查看它的一種替代方法:如果列不受約束並且返回多於1行,那麼這確實是一個系統錯誤。 – Kendrick 2010-10-21 19:11:13

+0

你對上面和其他的事情都是對的。 – signetro 2010-10-22 05:34:39

1
IF(@Count>0) 
    BEGIN 
    SELECT @RetVal = 6 
     , @ErrMsg = 'A description with the same name exists. Please provide a unique name.' 
    GOTO ERROR    
    END 

使用內置StoredProcException在捕獲,這意味着:

 catch (StoredProcException spEx) 
     { 
      switch (spEx.ReturnValue) 
      { 
       case 6: 
        UserMessageException umEx= new UserMessageException(spEx.Message); 
        throw umEx; 
      } 
     } 

你可以通過我ssage as string而不是spEx.Message

+0

@ Soner-Gönül我知道這是舊的,但是你從哪裏得到StoredProcException?這不是一個有效的c#異常。 – Mike 2017-10-24 18:37:23

+0

@Mike這個答案是不是我的。問問Bharath吧。 – 2017-10-25 06:00:48