我有一个从更新前触发器调用的存储过程。在这个过程中,我检查一些条件,如果满足,抛出异常
问题:异常显示了很多我不想显示给用户的数据:
例外4
Exception_Name
程序'proc_name'行:3,col: 50
在触发器'trigger_name'行:8,col: 17.
是否有一种方法可以只显示消息?如果没有,是否有办法停止更新而不抛出异常?
我使用Firebird 2.5.1与Delphi 2010DB连接:从post方法
回答有点晚,但总比不好。
这是我的解决方案。不太好也不太专业,有点像黑客,但我还没有找到更好的选择。
我在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;
异常很可能对错误的每个部分都有属性。您可以查看异常类的声明(在您的问题中没有提供)。例如,EDatabaseError
具有ErrorCode
和ErrorMessage
的性质;我怀疑FireBird错误也有它们。
这意味着你的异常处理程序可以做这样的事情:
try
.. some database thing
except
on E: EFireBirdException do
ShowMessage(E.ErrorMessage);
end;
注意,我不知道FireBird异常类提供了什么;我只是提供了你应该在Firebird异常类声明中寻找的东西的类型。其他有用的值通常是ErrorCode
。
同样,要查看异常类声明中可用的内容以及异常类的特定功能(如E.Message、E.Code等),您需要查看正在处理的特定类。