如何从 Ado.net 捕获 Sql Server 错误

Gre*_*Gum 5 c# ado.net sql-server-2008-r2

我有以下调用存储过程的代码。我希望能够捕获存储过程运行期间发生的任何错误。

try {
            using (var connection = GetConnection()) {

                using (SqlCommand cmd = connection.CreateCommand()) {
                    connection.Open();
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "VerifyInitialization";
                    cmd.Parameters.Add(new SqlParameter("@userId", user.Id));
                    cmd.Parameters.Add(new SqlParameter("@domainId", user.DomainId));
                    cmd.ExecuteNonQueryAsync();
                }

            }
        }
        catch (Exception ex) {
            throw new LoginException(LoginExceptionType.Other, ex.Message);
        }
Run Code Online (Sandbox Code Playgroud)

这就是存储过程,它基本上只是调用其他存储过程。

 ALTER PROCEDURE [dbo].[VerifyInitialization] 
-- Add the parameters for the stored procedure here
@userId int, 
@domainId int
 AS
 BEGIN
Begin Try
SET NOCOUNT ON;
Exec VerifyInitializationOfDefaultLocalizationItems
Exec VerifyInitializationOfLayoutLists @domainId
Exec VerifyInitializationOfLayoutListItems @domainId
Exec VerifyInitializationOfLocalizationItems @domainId
Exec VerifyInitializationOfLookupLists @domainId
Exec VerifyInitializationOfLookupListItems @domainId
End try

Begin Catch
  -- Raise an error with the details of the exception
    DECLARE 
    @ErrMsg nvarchar(4000) = Error_message(), 
    @ErrSeverity int = ERROR_SEVERITY();

    RAISERROR(@ErrMsg, @ErrSeverity, 1) 
End Catch
End
Run Code Online (Sandbox Code Playgroud)

我需要做什么才能捕获存储过程中将返回到 C# 的错误?例如,字段名称被重命名,这会阻止存储过程之一运行。我不希望它默默地失败。

格雷格

Bri*_*ian 3

在您的情况下使用ExecuteNonQueryAsync()不如使用ExecuteNonQuery()

try {
   using (var connection = GetConnection()) {
      using (SqlCommand cmd = connection.CreateCommand()) {
         connection.Open();
         cmd.CommandType = CommandType.StoredProcedure;
         cmd.CommandText = "VerifyInitialization";
         cmd.Parameters.Add(new SqlParameter("@userId", user.Id));
         cmd.Parameters.Add(new SqlParameter("@domainId", user.DomainId));
         //cmd.ExecuteNonQueryAsync(); - This line should be .ExecuteNonQuery()
         cmd.ExecuteNonQueryAsync(); 
      }
   }
}

catch (Exception ex) {
   throw new LoginException(LoginExceptionType.Other, ex.Message);
}
Run Code Online (Sandbox Code Playgroud)

您可能需要考虑的另一件事是捕获更具体的SqlException而不是更笼统的Exception,如下所示:

catch (SqlException exc) {
   throw new SqlException(/* Handle your exception messaging here. */);
}

catch (Exception ex) {
   throw new LoginException(LoginExceptionType.Other, ex.Message);
}
Run Code Online (Sandbox Code Playgroud)

编辑:我发布了这个答案,但没有意识到@usr 已经在上面的评论中回答了它。如果你喜欢我会删除。