2014-01-06 1 views
5

을 잡기 TCustomADODataSet 때 EditTADODataSetPost을, 나는 ADO에 의해 제기 예외 얻을 :(다중 사용자 환경에서) 어떤 상황에서 EOleException (안 EDatabaseError)

"행이 시설을 할 수 없습니다 마지막으로 읽은 이후로 일부 값이 으로 변경되었을 수 있습니다. "

IDE에서 프로그램을 실행하는 경우 오류 번호 -2147217864EOleException으로 예외가 발생합니다.
이 예외를 잡을 수 있기를 원하지만, IDE 외부에서 프로그램을 실행할 때 예외가 발생합니다. EDatabaseError에는 ErrorCode이 필요합니다. 당신이 ADODB.TCustomADODataSet.InternalPost를 보면

procedure TForm1.DataSetCommit(ds: TADODataSet); 
begin 
    ds.Connection.BeginTrans; 
    try  
    try 
     ds.Post; // <- Exception is raised here 
    except 
     on E: EOleException do; // EOleException is NOT fired! (E.ErrorCode = -2147217864) - see "ADODB.TCustomADODataSet.InternalPost" 
     on E: EDatabaseError do 
     begin 
     // todo: Handle this situation 
     end; 
    end; 
    ds.Connection.CommitTrans; 
    except 
    ds.Connection.RollbackTrans; 
    raise; 
    end; 
end; 

당신이 너무로 싸여 있음을 알 수 있습니다 :

procedure TCustomADODataSet.InternalPost; 
begin 
    UpdateCursorPos; 
    try 
    ... // <- Exception is raised here 
    except 
    on E: Exception do 
     DatabaseError(E.Message); 
    end; 
    CheckForFlyAway; 
end; 

를 예외가 로컬 프로 시저 UpdateData 내에서 발생 : Recordset.Update(EmptyParam, EmptyParam);EOleException를 트리거 여기에 내 코드의 일부입니다 (내가 필요한) 래퍼는 EDatabaseError을 발생시킵니다! (grrrrrrr).

제 질문은 EOleException.ErrorCode을 쿼리 할 수 ​​있도록 원래 EOleException을 어떻게 만듭니 까?

+1

이제 RTL 코드를 보았으므로 메모리에있는 해당 프로 시저를 바이너리 패치하거나 RTL의 ExceptProc을 하이재킹하여 주소 필터링을 수행하고 EOLEException을 정규화 된 메시지 텍스트 (예 : json)에 필요한 모든 매개 변수가 포함됩니다. –

+0

EOleException 개체는 TCustomADODataSet.InternalPost에 의해 해제됩니다. 나는 당신이 스택에서 그것을 찾기 위해 바뀌 었다고 생각하지 않는다. 당신이 그것을 해결 했다니 다행 –

+0

@ Arioch'The, 어떻게 풀 수 있다고 말할 수 있습니까? – kobik

답변

2

나는 아무 소용에 TRaiseFrame.NextRaise를 얻기 위해 System.RaiseList을 활용하기 위해 노력했습니다 - 내가 원하는 EOleException받지 못했습니다 ... 그래서 나는 내 경우에 특정입니다 오히려 우아한 해결책 (ADO)를 발견하고 RTL에에 의존하지 않는 - 나는 TADODataSet.ConnectionErrors 객체 테스트 해요 :

procedure TForm1.DataSetCommit(ds: TADODataSet); 
begin 
    ds.Connection.BeginTrans; 
    try  
    try 
     ds.Post; 
    except   
     on E: EDatabaseError do 
     begin   
     if Assigned(ds.Connection.Errors) and (ds.Connection.Errors.Count > 0) then 
      with ds.Connection.Errors.Item[0] do 
      // if (Number = -2147217864) then ... 
      ShowMessage(Format('Number:%d; Source:%s; Description:%s; NativeError:%d; SQLState:%s', 
       [Number, Source, Description, NativeError, SQLState])); 
     end; 
    end; 
    ds.Connection.CommitTrans; 
    except 
    ds.Connection.RollbackTrans; 
    raise; 
    end; 
end; 

이 특정 문제에 대한 나의 해결책이 될 것이다,하지만 난 여전히 다른 아이디어에 관심이 방법 트랩 이전 EOleException 예외.