我有一個從更新前觸發器調用的存儲過程。在這個過程中我檢查一些條件,如果滿足一個異常被拋出僅顯示火鳥異常消息
問題異常顯示很多數據,我不希望展現給用戶:
例外4
Exception_Name
錯誤消息在過程 'proc_name中' 線:3,西:50
在觸發 'TRIGGER_NAME' 線:8,西:17.
是否有僅顯示消息的方法嗎?如果沒有,有沒有辦法停止更新而不拋出異常?
我用火鳥2.5.1與2010年德爾福 DB連接:IBDac和更新由POST方法
我有一個從更新前觸發器調用的存儲過程。在這個過程中我檢查一些條件,如果滿足一個異常被拋出僅顯示火鳥異常消息
問題異常顯示很多數據,我不希望展現給用戶:
例外4
Exception_Name
錯誤消息在過程 'proc_name中' 線:3,西:50
在觸發 'TRIGGER_NAME' 線:8,西:17.
是否有僅顯示消息的方法嗎?如果沒有,有沒有辦法停止更新而不拋出異常?
我用火鳥2.5.1與2010年德爾福 DB連接:IBDac和更新由POST方法
異常最有可能對每個錯誤的部分特性觸發。你可以看看異常類的聲明(你沒有打算在你的問題中提供)。例如,EDatabaseError
具有ErrorCode
和ErrorMessage
的屬性;我懷疑FireBird錯誤也有。
這意味着,異常處理程序可能會做這樣的事情:
try
.. some database thing
except
on E: EFireBirdException do
ShowMessage(E.ErrorMessage);
end;
請注意,我不知道什麼火鳥異常類提供;我只是提供了你應該在Firebird異常類聲明中尋找的類型。其他有用的值通常是ErrorCode
。
同樣,要查看異常類聲明中可用的內容,以及異常類的特定功能(如E.Message,E.Code等等,您需要查看具體的類,重新處理。
有點晚了答案,但比從來沒有後來。
這裏是我的解決辦法。不要太漂亮或專業,那種黑客,但我還沒有發現任何更好的選擇。
我修改了以下程序中的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;
這是一個比火鳥更多的德爾福問題。您應該包含一些關於如何執行Delphi更新以及用於連接到數據庫的組件的信息。 – jachguate 2013-03-26 02:43:44
在我們基於FB的應用程序(與Oracle幾乎相同)中:捕獲異常;分析它,獲得本地化的消息,用像real_ex_message ||這樣的文本引發異常'##'|| human_ex_message;在客戶端應用程序中解析前消息,並在'##'後僅顯示部分內容。 – Abelisto 2013-03-26 03:17:33
@jachguate info now now – Wel 2013-03-26 03:20:54