1

我有一个从更新前触发器调用的存储过程。在此过程中,我检查某些条件,如果遇到异常则抛出

异常显示许多我不想向用户显示的数据的问题:

异常 4
Exception_Name
错误消息在过程“proc_name”行:3,col:50
在触发器“trigger_name”行:8,col:17。

有没有办法只显示消息?如果没有,有没有办法在不引发异常的情况下停止更新?

我正在使用带有 Delphi 2010 DB 连接的 Firebird 2.5.1:IBDac 和更新是从 post 方法触发的

4

2 回答 2

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;
于 2015-06-24T22:20:47.880 回答
0

异常很可能具有错误的每个部分的属性。您可能会查看异常类的声明(您没有费心在问题中提供)。例如,EDatabaseError具有ErrorCode和的属性ErrorMessage;我怀疑 FireBird 错误也有它们。

这意味着您的异常处理程序可以执行以下操作:

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

请注意,我不知道 FireBird 异常类提供了什么;我只是提供你应该在 Firebird 异常类声明中寻找的类型。其他有用的值通常是ErrorCode.

同样,要查看异常类声明和异常类的特定功能(如 E.Message、E.Code 等)中可以使用的内容,您需要查看正在处理的特定类。

于 2013-03-26T03:08:19.440 回答