2013-03-26 57 views
1

我有一個從更新前觸發器調用的存儲過程。在這個過程中我檢查一些條件,如果滿足一個異常被拋出僅顯示火鳥異常消息

問題異常顯示很多數據,我不希望展現給用戶:

例外4
Exception_Name
錯誤消息在過程 'proc_name中' 線:3,西:50
在觸發 'TRIGGER_NAME' 線:8,西:17.

是否有僅顯示消息的方法嗎?如果沒有,有沒有辦法停止更新而不拋出異常?

我用火鳥2.5.1與2010年德爾福 DB連接:IBDac和更新由POST方法

+1

這是一個比火鳥更多的德爾福問題。您應該包含一些關於如何執行Delphi更新以及用於連接到數據庫的組件的信息。 – jachguate 2013-03-26 02:43:44

+1

在我們基於FB的應用程序(與Oracle幾乎相同)中:捕獲異常;分析它,獲得本地化的消息,用像real_ex_message ||這樣的文本引發異常'##'|| human_ex_message;在客戶端應用程序中解析前消息,並在'##'後僅顯示部分內容。 – Abelisto 2013-03-26 03:17:33

+0

@jachguate info now now – Wel 2013-03-26 03:20:54

回答

0

異常最有可能對每個錯誤的部分特性觸發。你可以看看異常類的聲明(你沒有打算在你的問題中提供)。例如,EDatabaseError具有ErrorCodeErrorMessage的屬性;我懷疑FireBird錯誤也有。

這意味着,異常處理程序可能會做這樣的事情:

try 
    .. some database thing 
except 
    on E: EFireBirdException do 
    ShowMessage(E.ErrorMessage); 
end; 

請注意,我不知道什麼火鳥異常類提供;我只是提供了你應該在Firebird異常類聲明中尋找的類型。其他有用的值通常是ErrorCode

同樣,要查看異常類聲明中可用的內容,以及異常類的特定功能(如E.Message,E.Code等等,您需要查看具體的類,重新處理。

+0

不要猜測太多我不知道要包含哪些信息! – Wel 2013-03-26 03:18:18

+0

@Welliam不幸的是,沒有ibdac標籤來引起該連接層的一些專家的注意。如果您有可用的源代碼,您可以在那裏瞭解引發異常的屬性。您還可以觸發代碼完成來檢查異常對象爲您提供的內容。 – jachguate 2013-03-26 04:06:08

+0

@jachguate好的謝謝 – Wel 2013-03-26 04:45:21

1

有點晚了答案,但比從來沒有後來。

這裏是我的解決辦法。不要太漂亮或專業,那種黑客,但我還沒有發現任何更好的選擇。

我修改了以下程序中的IB.pas文件(IBX),工作正常。我知道使用不同的包來訪問數據庫的OP,但我想邏輯將是相同的。

procedure IBDataBaseError; 
var 
    sqlcode: Long; 
    IBErrorCode: Long; 
    local_buffer: array[0..IBHugeLocalBufferLength - 1] of char; 
    usr_msg: string; 
    status_vector: PISC_STATUS; 
    IBDataBaseErrorMessages: TIBDataBaseErrorMessages; 
    AStrList: TStringList; 
    i: integer; 
begin 
    usr_msg := ''; 

    { Get a local reference to the status vector. 
    Get a local copy of the IBDataBaseErrorMessages options. 
    Get the SQL error code } 
    status_vector := StatusVector; 
    IBErrorCode := StatusVectorArray[1]; 
    IBDataBaseErrorMessages := GetIBDataBaseErrorMessages; 
    sqlcode := GetGDSLibrary.isc_sqlcode(status_vector); 

    if (ShowSQLCode in IBDataBaseErrorMessages) then 
    usr_msg := usr_msg + 'SQLCODE: ' + IntToStr(sqlcode); {do not localize} 
    Exclude(IBDataBaseErrorMessages, ShowSQLMessage); 
    if (ShowSQLMessage in IBDataBaseErrorMessages) then 
    begin 
    GetGDSLibrary.isc_sql_interprete(sqlcode, local_buffer, IBLocalBufferLength); 
    if (ShowSQLCode in IBDataBaseErrorMessages) then 
     usr_msg := usr_msg + CRLF; 
    usr_msg := usr_msg + string(local_buffer); 
    end; 

    if (ShowIBMessage in IBDataBaseErrorMessages) then 
    begin 
// unnecessary code 
// if (ShowSQLCode in IBDataBaseErrorMessages) or 
//  (ShowSQLMessage in IBDataBaseErrorMessages) then 
//  usr_msg := usr_msg + CRLF; 
    while (GetGDSLibrary.isc_interprete(local_buffer, @status_vector) > 0) do 
    begin 
     if (usr_msg <> '') and (usr_msg[Length(usr_msg)] <> LF) then 
     usr_msg := usr_msg + CRLF; 
     usr_msg := usr_msg + string(local_buffer); 
    end; 

    // then next condition is optional, remove if you use other 
    // initialization than SetIBDataBaseErrorMessages([ShowIBMessage]) 
    if (IBDataBaseErrorMessages = [ShowIBMessage]) then 
    begin 
     AStrList:= TStringList.Create; 
     try 
     AStrList.Text:= usr_msg; 
     // apply to user defined exception only 
     if (AStrList.Count > 0) and (Pos('exception', AStrList[0]) = 1) then 
      // i'm using ! on the end of every exception 
      // if you don't, just simply keep the 3. line (AStrList[2]) 
      // of AStrList and delete the rest of lines 
      for i:= AStrList.Count - 1 downto 0 do 
      if (Pos('!', AStrList[i]) = 0) then 
       AStrList.Delete(i); 
     usr_msg:= AStrList.Text; 
     finally 
     AStrList.Free; 
     end; 
    end; 
    end; 

    while (usr_msg <> '') and ((usr_msg[Length(usr_msg)] = '.') or (usr_msg[Length(usr_msg)] = LF) or (usr_msg[Length(usr_msg)] = CR)) do 
    Delete(usr_msg, Length(usr_msg), 1); 
    MonitorHook.SendError(IntToStr(sqlcode) + ' ' + IntToStr(IBErrorCode) + ' ' + usr_msg); 
    if sqlcode <> -551 then 
    raise EIBInterBaseError.Create(sqlcode, IBErrorCode, usr_msg) 
    else 
    raise EIBInterBaseRoleError.Create(sqlcode, IBErrorCode, usr_msg) 
end;