【问题标题】:Catch the error from Stored Procedure in C#从 C# 中的存储过程中捕获错误
【发布时间】:2010-10-21 17:37:49
【问题描述】:

我有一个在登录期间调用以验证用户的存储过程。 如果成功,它会返回用户实体,效果很好!我的问题是,如果它不起作用,我将在 SP 中引发错误,我如何捕获此错误并以最佳方式使用它?现在我得到空引用,这是代码: 存储过程:

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;
            }

我的问题是我应该如何处理异常?

【问题讨论】:

    标签: c# .net linq linq-to-sql stored-procedures


    【解决方案1】:

    我通常不会从 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
    

    【讨论】:

    • 同意!这并不是真正的“错误”,当然也不应该从数据库中引发。
    • 是的,你是对的,这不是错误,所以我应该更改它,但是我应该如何编写 SP,如果成功,我仍然想从数据库返回完整的实体,但是让我们如果什么都没有说0,我应该如何更改我的SP? /谢谢
    • 从上面的过程中,您应该能够检查返回值以查看它包含多少项。如果它是一个空集,您就知道用户名/密码有问题。如果里面有 1 个项目,他们可以登录,如果有多个项目(假设你觉得强迫症需要检查,因为数据库应该确保这种情况),那么就有一个严重的问题 :-)
    • 呵呵,没错!感谢您的帮助,为了清楚起见,如果有人稍后阅读此内容,我现在从我的 SP 中删除了 RAISERROR,现在只选择 * ,并且在我的代码中我计算如下: var getemp = dc.getEmployee1(piUsername , pi密码); if (getemp.Count() > 0) { AppHelper.AppHelper.setUser(emp);返回真; } 否则 { 返回错误; }
    【解决方案2】:

    您的 InnerException 可能为 null。

    您应该尝试捕获并处理特定的异常,在本例中为SqlExceptions

    【讨论】:

      【解决方案3】:
         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
      }
      

      【讨论】:

      • 请注意:如果 eUsername 在不允许重复的列中是唯一的(并且应该是唯一的),则“前 1”是多余的。另一种看待它的方式:如果列不受约束并且返回多于 1 行,那么这确实是系统错误。
      【解决方案4】:
        IF(@Count>0)  
        BEGIN   
        SELECT  @RetVal = 6  
              , @ErrMsg = 'A description with the same name exists. Please provide a unique name.'  
        GOTO ERROR            
        END 
      

      在 catch 中使用内置的 StoredProcException,这意味着:

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

      您可以将消息作为字符串而不是 spEx.Message 传递

      【讨论】:

      • @Soner-Gönül 我知道这是旧的,但你从哪里得到 StoredProcException?这不是一个有效的 c# 异常。
      • @Mike 这个答案不是我的。改为询问 Bharath。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2014-11-27
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多