1

I am using Delphi 2009 Unicode and Firebird 3.x UTF8/dialect 3 database with IBX components. And now I see that all the exceptions raised from the Firebird SQL procedure and trigger code (e.g. using exception my_exception; statement) are handled by IBX as special Firebird exceptions:

Attempt to execute an unprepared dynamic SQL statement
Error Code: 335544711 SQL Code: -901

IBX does not report the name/code/content of the original Firebird exception. It is quite strange, because Delphi 2009 IBX can handle Firebird 2.1 UTF8/Unicode exceptions without problems. It seems to me that IBX is trying to do some extra steps that are not allowed.

Of course, I know that all the advices to move to other frameworks from the IBX, but we are not living in the ideal world, so, the question is as it is.

Question extended: After initialization code in the project file (this is IB routine http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/IB_SetIBDataBaseErrorMessages.html):

SetIBDataBaseErrorMessages([ShowSQLCode,ShowIBMessage,ShowSQLMessage]);

I am getting normal error messages from the exceptions that are raised from the triggers, but I am still getting generic 'Attempt to execute...' error message in the case when exception is raised from the SQL procedure.

Question updated: The generic exception about attempt appears when the procedure is called from the IBX TIBStoredProc, but if stored procedure is called (via select from...) from the TIBDataSet, then the right error message appears. So - there should be problem how TIBStoredProc handles the error messages.

TomR
  • 2,696
  • 6
  • 34
  • 87
  • Please post a [mcve]. As it stands it is hard to understand exactly what you're asking. The error itself seems to indicate a usage error (trying to execute a statement without preparing), at least fbclient (and in some cases, Firebird server), raises this error if you try to execute, fetch, ask for statement info, describing binds, etc without having prepared a statement on the statement handle. – Mark Rotteveel Oct 07 '18 at 16:14
  • Are you saying that the behaviour of your app has recently changed or what? In any case, what is your q? – MartynA Oct 07 '18 at 16:15
  • I used Firebird 2.1 up to now but now I have migrated database to the Firebird 3.0 and I am trying to use this database from the old Delphi 2009 Unicode app and all the Firebird exceptions appear as such. – TomR Oct 07 '18 at 16:19
  • I updated question 2 times with the additional info, TIBStoredProc has some bug apparently? – TomR Oct 07 '18 at 16:43

1 Answers1

1

Debug shows, that Delphi IBX code IBSQL.pas contains code:

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

and the error message about unprepared statement is raised exactly upon the second execution isc_dsql_execute2(...), so - maybe such second try is not necessary and we can raise Exception IBDataBaseError whenever the fetch_res is not 0? Maybe someone knows why Jeff introduced such second call and what bugs this second call tried to solve?

It appears, that Delphi XE 10.2 code makes the second call only in the specific case:

if (fetch_res = isc_bad_stmt_handle) then

And that makes the erroneous second call rare enough to solve the problem in my question. So, the solution is to replace the initial general condition (fetch_res <> isc_lock_conflict) with the more specific condition (fetch_res = isc_bad_stmt_handle).

TomR
  • 2,696
  • 6
  • 34
  • 87
  • 1
    "Sometimes a prepared stored procedure " - all this sh%t is a long known problem: Interbase team refused to fix the bug in Interbase, so IBX team had to *introduce* a special bug trying to counter IB bug. Since Firebird team fixed the original bug then the IBX added bug surfaced. It is not easy to call FB's SP's with IBX... – Arioch 'The Oct 08 '18 at 08:58
  • Just for those who will read the previous comment and who will be in position to advise/take decisions: I have very good experience with Firebird (<=2.1)/IBX (<=Delphi 2009) and this issue is the only one that surfaces when moving to Firebird 3.x/UTF8/Dialect 3. Of course, there are conventions to be discovered and used regarding BLOB/Memo fields, there are limits on data amount (IBDataSet does not read more than 1GB data), but generally the combination Firebird/IBX seems to be quite good for production, I don't know why there are so much against it. It is better than unexplored alternatives. – TomR Oct 08 '18 at 09:14
  • 1
    Because for Embarcadero Firebird is direct competitor. In standard IBX you can not even provide "fbclient.dll" filename without patching. Or without copy-pasting all the library class implementation. It is just that they do not want it. So - it is an uphill battle. Given "unexplored alternatives" where FB is not unwanted child forced upon you, given even something in Lazarus called IBX2 - why to pick such a battle? YMMV // BTW - did you tried IBX FB Utils wrapper ? – Arioch 'The Oct 08 '18 at 11:01
  • 1
    With all my disdain for IBX+FB mix, I have to admit sometimes it is quite handy wrapper - http://loginovprojects.ru/index.php?page=ibxfbutils - u would have to download the http://loginovprojects.ru/download.php?getfilename=uploads/other/ibxfbutils.zip and look into unittests/examples though – Arioch 'The Oct 08 '18 at 11:10
  • 1
    BTW, think about it, the fix in IBX 10.2 could be applied loooong ago, but it only happened when supposedly the bug was fixed in Interbase itself, and so this IBX quirk started haunting them too. Just this very approach, cultivating incompatibilities with FB (good that not intentional creating those) is troublesome for me. BTW, try to use FB3's Boolean type fields – Arioch 'The Oct 09 '18 at 13:22
  • RE: we are gradually migrating to Zeos components, but we have to use IBX while this process is continuing. I guess, that Zeos are quite good and they are open source and they keep the BDE ideology (e.g. in transaction management) that is not so bad. And another observation - nothing can win BDE in speed/performance (I guess it was due to being lightweight), sad that Borland chose not to open source it. – TomR Oct 09 '18 at 13:32
  • 1
    Lol, I know ppl hating Zeos, and remembering the neverending stream of Zeos 6.99999999.... I can somewhat relate. Though other people told me that once unlucky Zeos 7 finally was born it matures pretty well, dunno did not try myself. – Arioch 'The Oct 09 '18 at 14:16
  • Thx a lot, it's helpful even in 2023 :) – GeorgeKarlinzer May 29 '23 at 12:27