2013-03-26 119 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;