• 谈谈基于SQL Server 的Exception Handlingp[下篇]


    六、SqlException

    在上面一节中,我给出了一个完整的例子说明了:如何在将message定义在sys.messages中保证message的一致性和可维护性;如何在Stored procedure中使用RAISERROR将一个可预知的Error抛出;如何在Stored procedure中使用TRY/CATCH进行异常的捕捉;在Application如果处理从SQL Server抛出的Exception。实际上,SQL Server database Engine抛出、被我们的.NET最终捕获的SqlException,我们通过SqlException的属性可以得到Error的相关信息。下面是SqlException的属性列表:

    • public SqlErrorCollection Errors { get; }
    • public int LineNumber { get; }
    • public int Number { get; }
    • public string Procedure { get; }
    • public string Server { get; }
    • public override string Source { get; }
    • public byte State { get; }


    有了前面的内容作铺垫,相信大家都知道每个属性分别表示的什么了吧。为了使大家对

    stored procedureErrorADO.NET捕获的ErrorMapping有一个更加清晰的认识。我们来写一个Sample,我们沿用Create User的例子:

    stored procedure中,遇到重名通过RAISERROR抛出异常[在整篇文章中,使用到ErrorException,大家可以看成是等效的]
        ·         Error Number50001
        ·         Severity16
        ·         State1
        ·         MessageThis user is already existent

    我们来修正一下CreateUser方法:

    public static  bool CreateUser(string userName)
            
    {
                
    string procedureName = "P_USERS_I";
                Dictionary
    <stringobject> parameters = new Dictionary<stringobject>();
                parameters.Add(
    "user_id", Guid.NewGuid().ToString());
                parameters.Add(
    "user_name", userName);
                
    try
                
    {
                    ExecuteCommand(procedureName, parameters);
                    
    return true;
                }

                
    catch (SqlException ex)
                
    {
                    Console.WriteLine(
    "ex.Class\t: {0}", ex.Class);
                    Console.WriteLine(
    "ex.ErrorCode\t: {0}", ex.ErrorCode);
                    Console.WriteLine(
    "ex.LineNumber\t: {0}", ex.LineNumber);
                    Console.WriteLine(
    "ex.Message\t: {0}", ex.Message);
                    Console.WriteLine(
    "ex.Number\t: {0}", ex.Number);
                    Console.WriteLine(
    "ex.Procedure\t: {0}", ex.Procedure);
                    Console.WriteLine(
    "ex.Server\t: {0}", ex.Server);
                    Console.WriteLine(
    "ex.Source\t: {0}", ex.Source);
                    Console.WriteLine(
    "ex.State\t: {0}", ex.State);
             
    return false;
                }

            }

    Main()中调用这个CreateUser():



    在这里我想特别说明一下
    SqlException.Number这个属性,它代表Database中的Error number[或者是@@ERRORimessage_id],不过当我们使用RAISERROR语句,如果我们指定的一个表示error message的字符串,ADO.NET捕获的SqlException.Number这个属性默认为50000。比如我们将Error number换成error message

    SET @error_message    = ERROR_MESSAGE()
    SET @error_serverity    =ERROR_SEVERITY()
    SET @error_state    = ERROR_STATE()
    RAISERROR(@error_message@error_serverity,@error_state)

    将会得到这样的结果:



    还有一点需要特别提醒得是,我们可以在调用
    RAISERROR加了一个WITH SETERROR重句,强制将当前@@ERROR的值返回到客户端:

    RAISERROR(@error_message,@error_serverity,@error_stateWITH SETERROR

    七、    InfoMessage

    上面的所以内容都围绕一个Exception handling的主题,在文章最后一部分我们想想一个和非Exception handling但是又和上面的内容很相关的主题:在Database通过Print语句输出的Message如何向Application传递。

    在上面的例子中,有一个P_CLEAR_DATAstored procedure,用于数据的清理。在操作结束后,有一个Print语句(PRINT ('All data have been deleted!')

    CREATE Procedure P_CLEAR_DATA
    AS

        
    DELETE FROM dbo.T_USERS_IN_ROLES
        
    DELETE FROM dbo.T_USERS
        
    DELETE FROM dbo.T_ROLES
        
        
    PRINT ('All data have been deleted!')
        
    GO

    我们的现在的目标是在Application中,如何得到这段Message。要做到这点很简单,只需要用到SqlConnectionInfoMessage事件,当通过DbCommand执行上面一段Sql的时候,Print语句的执行将出发该事件。我们现在要做的就是注册这个事件,比如下面我们在ExecuteCommand()种添加了下面一段代码:

    SqlConnection sqlConnection = connection as SqlConnection;
     
    if (sqlConnection != null)
        
    {
              sqlConnection.InfoMessage 
    += delegate(object sender, SqlInfoMessageEventArgs e)
              
    {
                            Console.WriteLine(e.Message);
               }
    ;
         }

     当我们调用Utility.Clear()的时候,就会输出"All data have been deleted!"



    [原创]谈谈基于SQL Server的Exception Handling - PART I
    [原创]谈谈基于SQL Server 的Exception Handling - PART II
    [原创]谈谈基于SQL Server 的Exception Handling - PART III 

  • 相关阅读:
    ASE19团队项目 beta阶段 model组 scrum report list
    ASE19团队项目 beta阶段 model组 scrum7 记录
    ASE19团队项目 beta阶段 model组 scrum6 记录
    ASE19团队项目 beta阶段 model组 scrum5 记录
    ASE19团队项目 beta阶段 model组 scrum4 记录
    ASE19团队项目 beta阶段 model组 scrum3 记录
    ASE19团队项目 beta阶段 model组 scrum2 记录
    ASE19团队项目 beta阶段 model组 scrum1 记录
    【ASE模型组】Hint::neural 模型与case study
    【ASE高级软件工程】第二次结对作业
  • 原文地址:https://www.cnblogs.com/artech/p/1002857.html
Copyright © 2020-2023  润新知