1

before update トリガーから呼び出されるストアド プロシージャがあります。この手順では、いくつかの条件をチェックし、満たされた場合は例外がスローされます

例外がユーザーに表示したくない多くのデータを表示する問題:

例外 4
Exception_Name
エラー メッセージ プロシージャ 'proc_name' 行: 3、列: 50
トリガー 'trigger_name' 行: 8、列: 17。

メッセージだけを表示する方法はありますか? そうでない場合、例外をスローせずに更新を停止する方法はありますか?

Delphi 2010 DB接続でFirebird 2.5.1を使用しています:IBDacと更新はポストメソッドからトリガーされます

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 に答える