我正在使用带有IBX组件的Delphi 2009 Unicode和Firebird 3.x UTF8 / dialect 3数据库。现在,我看到IBX将Firebird SQL过程和触发器代码引发的所有异常(例如,使用exception my_exception;
语句)作为特殊的Firebird异常处理:
Attempt to execute an unprepared dynamic SQL statement
Error Code: 335544711 SQL Code: -901
IBX不报告原始Firebird异常的名称/代码/内容。这很奇怪,因为Delphi 2009 IBX可以毫无问题地处理Firebird 2.1 UTF8 / Unicode异常。在我看来,IBX试图做一些不允许的额外步骤。
当然,我知道从IBX转移到其他框架的所有建议,但我们并不生活在理想的世界中,所以问题就在这里。
问题扩展: 在项目文件中的初始化代码之后(这是IB例程http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/IB_SetIBDataBaseErrorMessages.html):
SetIBDataBaseErrorMessages([ShowSQLCode,ShowIBMessage,ShowSQLMessage]);
我从触发器引发的异常中获取正常的错误消息,但是在从SQL过程中引发异常的情况下,我仍然得到通用的“尝试执行...”错误消息。
问题已更新: 从IBX TIBStoredProc调用该过程时,会出现有关尝试的一般异常,但是如果从TIBDataSet调用存储过程(通过select ...),则会出现正确的错误消息。因此-TIBStoredProc如何处理错误消息应该存在问题。
答案 0 :(得分:0)
调试显示,Delphi IBX代码IBSQL.pas包含代码:
SQLExecProcedure:
begin
fetch_res := Call(FGDSLibrary.isc_dsql_execute2(StatusVector, TRHandle,
@FHandle, Database.SQLDialect, FSQLParams.AsXSQLDA,
FSQLRecord.AsXSQLDA), False);
if (fetch_res <> 0) then
begin
if (fetch_res <> isc_lock_conflict) then
begin
{ Sometimes a prepared stored procedure appears to get
off sync on the server ....This code is meant to try
to work around the problem simply by "retrying". This
need to be reproduced and fixed.
}
FGDSLibrary.isc_dsql_prepare(StatusVector, TRHandle, @FHandle, 0,
PByte(FProcessedSQL.Text), Database.SQLDialect, nil);
Call(FGDSLibrary.isc_dsql_execute2(StatusVector, TRHandle,
@FHandle, Database.SQLDialect, FSQLParams.AsXSQLDA,
FSQLRecord.AsXSQLDA), True);
end
else
IBDataBaseError; // go ahead and raise the lock conflict
end;
end
,并且在第二次执行isc_dsql_execute2(...)
时,就会引发关于未准备好的语句的错误消息,因此-也许不需要第二次尝试,并且只要fetch_res不为0,我们就可以引发Exception IBDataBaseError?也许有人知道为什么杰夫(Jeff)引入了这种第二通电话,以及该第二通电话试图解决哪些错误?
看来,Delphi XE 10.2代码仅在特定情况下才进行第二次调用:
if (fetch_res = isc_bad_stmt_handle) then
这使得错误的第二次呼叫不足以解决我的问题。因此,解决方案是将初始一般条件(fetch_res <> isc_lock_conflict)
替换为更具体的条件(fetch_res = isc_bad_stmt_handle)
。