在使用ado连接数据库中,在c/s结构中,我能通过adoconnection.errors来捕捉异常,可是当我试着把它用到三层中的时候,却发现捕捉不到异常,请问高手,该怎么才能捕捉到这种异常。

解决方案 »

  1.   

    三层结构,假定客户端看到的是业务逻辑层,业务逻辑层操作数据库的叫数据层。
    在给业务逻辑的接口函数中带上错误码和返回值,在数据层截获错误码Raise到上层,上层进行判断,变成自定义的错误码和错误描述。
    例:数据层返回错误码
    raise Exception.Create(intToStr(self.DBConn.Errors.Item[0].NativeError));
    业务逻辑层
    on e:exception do
        begin
          根据E.Message进行操作
          self.SetAbort;
          exit;
        end;
      

  2.   

    苹果兄,我也是那样做的呀,下面是我的代码
    procedure TErrorMsgDM.GetADOError(out ErrorEnglishMsg, ErrorChineseMsg ,
      SourceMsg, DescriptionMsg: WideString; out NativeErrorMsg: Integer);
    var
       adoErrors : Errors ;
       adoError :  Error  ;
    //   iCount   :  integer ;
    begin
       adoErrors:=adoconError.Errors ;
    //   for iCount:=0 to adoErrors.Count-1 do
    //   begin
        if adoErrors.Count=0 then
            showmessage('没有错误')
        else begin
          ShowMessage('有错误');
          adoError  := adoErrors.Item[0] ;
          SourceMsg := adoError.Source ;
          DescriptionMsg := adoError.Description ;
          NativeErrorMsg := adoError.NativeError ;
         if not adotblError.Locate('ErrorID',NativeErrorMsg,[]) then
         begin
            ErrorChineseMsg:='-100' ; //DescriptionMsg ;
            ErrorEnglishMsg:='-100' ;//SourceMsg ;
         end
         else begin
           ErrorChineseMsg:=adotblError.fieldByname('ChineseMsg').AsVariant ;
           ErrorEnglishMsg:=adotblError.fieldByname('EnglishMsg').AsVariant ;
         end;
       end;
    end;但是,当我测试的时候,在客户端插入一条记录,发生主键重复的错误,通过dcomconnection.appserver.getADOError来捕获错误的时候,却捕获不到,我怀疑三层的错误处理机制不是这样的,请教苹果兄
      

  3.   

    嘻嘻,对MIDAS不熟的说。
    这个错误函数是怎么引发的呢?
    我是将对数据库的操作放在try中,在except中raise错误码。就像普通的异常处理一样。
    看看其它熟悉MIDAS的兄弟怎么说。
    总感觉MIDAS的三层不像Windows的DNA架构,有时间找众兄弟讨论讨论。
      

  4.   

    苹果兄,因为我的三层结构是个很简单的三层结构,在客户端完成对数据库的添加、删除、更新、修改等操作,在客户端,通过DCOMConnection组件来连接COM+组件,所以当我在客户端对数据更新的时候,通过调用自定义的COM+接口函数,来取得DBConn.Errors.Item[0].NativeError的错误编号以及错误的详细信息。但是,取出来的都是空值(通过Errors.count来判断),不知道为什么。所以怀疑三层的错误处理机制不是这样的,但是不知道怎么处理,还请高手指教
      

  5.   

    我在TDataSetProvider的OnUpdateError事件中捕获错误,然后在ApplyUpdates时触发错误。
      

  6.   

    IAppServer 接口的 AS_ApplyUpdates 方法的返回值,就包含了错误信息!function AS_ApplyUpdates(const ProviderName: WideString; Delta: OleVariant; MaxErrors: Integer; out ErrorCount: Integer; var OwnerData: OleVariant): OleVariant; safecall;然后调用 TClientDataSet 的 Reconcile 方法,就会激发 OnReconcileError 事件,从而可以处理错误。
    TClientDataSet.ApplyUpdates 方法其实就是封装了上述的过程。
      

  7.   

    当然你也可以 在接口中自定义一个更新数据的方法,不用 IAppServer.AS_ApplyUpdates 。比如 : IMyAppServer.ApplyDataUpdate(……) ;  调用约定使用 safecall。这样在方法执行的过程中,如果更新数据有错,可以直接抛出异常。这个异常能够被客户端捕捉到!例如,客户端代码:
    try
      ……
      IMyAppServer.ApplyDataUpdate(……) ;
      ……
    except
      on e: EOleException do
      ……
    end;
      

  8.   

    TClientDataSet 的 Reconcile 方法,传回的是E:EReconcileError,但是这只能得到ADO异常的大类,例如,我们想捕获主键错误,参照完整性错误等这些小类的时候,我发现TClientDataSet 的 Reconcile 方法好象做不到,我只有得到小类,才能把通过在数据库中查找他们的他们中文。(在数据库中我定义了错误ID,错误内型,错误英文提示,错误中文提示)。