SqlException捕获和处理

Val*_*mas 60 c# exception sqlexception

问:有没有更好的方法来处理SqlExceptions?

以下示例依赖于解释消息中的文本.

Eg1:如果表不存在,我有一个现有的try catch来处理.
忽略我可以检查表是否存在于第一位的事实.

try
{
    //code
}
catch(SqlException sqlEx)
{
        if (sqlEx.Message.StartsWith("Invalid object name"))
        {
            //code
        }
        else
            throw;
}
Run Code Online (Sandbox Code Playgroud)

Eg2:没有try catch显示重复的键异常

if (sqlEx.Message.StartsWith("Cannot insert duplicate key row in object"))
Run Code Online (Sandbox Code Playgroud)

解决方案:我的SqlExceptionHelper的开始

//-- to see list of error messages: select * from sys.messages where language_id = 1033 order by message_id
public static class SqlExceptionHelper
{
    //-- rule: Add error messages in numeric order and prefix the number above the method

    //-- 208: Invalid object name '%.*ls'.
    public static bool IsInvalidObjectName(SqlException sex)
    { return (sex.Number == 208); }

    //-- 2601: Cannot insert duplicate key row in object '%.*ls' with unique index '%.*ls'. The duplicate key value is %ls.
    public static bool IsDuplicateKey(SqlException sex)
    { return (sex.Number == 2601); }
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*der 134

SqlException有一个可以检查的Number属性.对于重复错误,该数字为2601.

catch (SqlException e)
{
   switch (e.Number)
   {
      case 2601:
         // Do something.
         break;
      default:
         throw;
   }
 }
Run Code Online (Sandbox Code Playgroud)

要从服务器获取所有SQL错误的列表,请尝试以下操作:

 SELECT * FROM sysmessages
Run Code Online (Sandbox Code Playgroud)

更新

现在可以在C#6.0中简化

catch (SqlException e) when (e.Number == 2601)
{
   // Do something.
}
Run Code Online (Sandbox Code Playgroud)


Rem*_*anu 20

有点像.请参阅数据库引擎错误的原因和解决方法

class SqllErrorNumbers
{ 
   public const int BadObject = 208;
   public const int DupKey = 2627;
}

try
{
   ...
}
catch(SqlException sex)
{
   foreach(SqlErrorCode err in sex.Errors)
   {
      switch (err.Number)
      {
      case SqlErrorNumber.BadObject:...
      case SqllErrorNumbers.DupKey: ...
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

但问题是,我们TRY/CATCH T-SQL(存储过程)中使用了一个好的DAL层,其模式包括异常处理和嵌套事务.唉,一个T-SQL TRY/CATCH块无法引发原始错误代码,将不得不引发一个错误,代码高于50000.这使得客户端处理问题.在下一版本的SQL Server中,有一个新的THROW结构,允许从T-SQL catch块重新引发原始异常.

  • 感谢您的建议和链接.顺便说一句:我喜欢捕捉性爱:)我将开始使用它而不是sqlEx来获得乐趣.让我想起旧的经典asp天`On Error Goto Hell` (9认同)
  • 这听起来不对,在性爱方面犯了错误。 (2认同)

Ale*_*Aza 7

最好使用错误代码,您不必解析.

try
{
}
catch (SqlException exception)
{
    if (exception.Number == 208)
    {

    }
    else
        throw;
}
Run Code Online (Sandbox Code Playgroud)

如何找出208应该使用:

select message_id
from sys.messages
where text like 'Invalid object name%'
Run Code Online (Sandbox Code Playgroud)