Главная страница | назад





Article #25188: Handling BDE Engine Errors

Problem:
A Delphi or C++ Builder generated application produces a BDE Engine exception.


Solution:
An exception was produced in the Delphi generated application due to an error 
from the RDBMS server (i.e InterBase), the BDE or an ODBC driver.

Using the Borland BDE Configuration Utility (BDECFG.EXE, or BDEADMIN.EXE) 
to examine the SQLQRYMODE property of the InterBase or Visigneic ODBC alias 
being used in the application. If the setting is  or set to LOCAL change the 
setting to SERVER.  Save the changes and exit the utility.

If the application is using a TDatabase component, bring the application up in 
Delphi and left double-click the mouse on the TDatabase component to bring 
up the Database Login dialog.  Change the SQLQRYMODE property in the 
parameters list box to SERVER, if the property is present.  Save and do a Build All.

At this point exiting the Delphi IDE and starting it again may be required so that 
the new changes in the BDE aliases will be re-read and accounted for.

                                                      SQLQRYMODE Settings 
                                 ========================================
:  The BDE  sends the SQL query string to the RDBMS server or the ODBC data 
                  source and if an error is returned the BDE will then parse the string itself and 
                  will send the parsed string (or strings)  to the server.  

LOCAL:  The BDE will parse the strings and send the parsed string (or strings) to the
                server.  

SERVER:  The BDE will send the SQL query string to the RDBMS  SERVER or the 
                   ODBC datasource.  If an error occurs then this will be returned through 
                   the BDE.

By changing the setting to SERVER the error returned will be in direct relation 
to the SQL query that was requested by the Delphi application.  Next, run the 
application and try to reproduce the exception.

When the exception is reproduced the BDE will take the resulting error 
from the server and will map it through one of its existing error codes 
and messages. If the error is "General SQL Error: " this indicates 
that an error occurred on the server and the BDE did not have a comparable 
or corresponding error message to map it to so it returned this error.  The  
 portion will be the error string that is returned from the server 
(or ODBC datasource). This is the easy case, match the error string with 
the errors listed in the InterBase Language Reference, or with a listing of 
ODBC errors.  

If another error is produced then it is uncertain if the error is from the server, 
the BDE, or an ODBC driver, this is the not-so-easy case.  Delphi provides a
way to look at where the error is coming from, follow the instructions in the 
following paragraphs.

To further track down the source of the exception start by placing a memo 
on the main form.  This memo will be used to display further information 
that is available in the BDE Engine Exception object. Next implement the 
following code snippet into the main form of the application:
   
unit dbughelp;

   interface

   uses
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
     StdCtrls, DB;

   type
     TForm1 = class(TForm)
     Memo1: TMemo;
     procedure FormCreate(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
       procedure MyHandler(Sender: TObject; E:Exception);
     end;

   var
     Form1: TForm1;

   implementation

   {$R *.DFM}


   procedure TForm1.FormCreate(Sender: TObject);
   begin
     Application.OnException := MyHandler;
   end;

   procedure TForm1.MyHandler(Sender: TObject; E: Exception);
   var
     i: Word;
     F: EBDEEngineError;
   begin
     Memo1.Lines.Add('== Begin Entries for Exceptions ==');
     Memo1.Lines.Add(E.ClassName);
     if (E is EBDEEngineError) then begin
       F := EBDEEngineError(E);
       Memo1.Lines.Add('ErrorCount = ' + IntToStr(F.ErrorCount));
       for i := 0 to F.ErrorCount - 1  do begin
         Memo1.Lines.Add(' ');
         Memo1.Lines.Add('----------');
         Memo1.Lines.Add(' ');
         Memo1.Lines.Add('NativeError = ' + IntToStr(F.Errors[i].NativeError));
         Memo1.Lines.Add('Message = ' + F.Errors[i].Message);
         Memo1.Lines.Add('ErrorCode = ' + IntToStr(F.Errors[i].ErrorCode));
       end;
     end;
     Memo1.Lines.Add('== End Entries for Exceptions ==');
   end;

end.

In the FormCreate procedure (i.e OnCreate event) the application global 
exception handler is re-routed to a custom exception handler, the Myhandler 
procedure.  Within the MyHandler procedure the error information in the BDE 
Engine Exception object is placed in the memo component.  After the BDE 
Engine Exception information is placed in the memo look for the NativeError 
codes. The errors will follow a specific pattern for InterBase , the BDE and for 
ODBC.  The patterns of the error messages are:

InterBase:  The errors will follow the pattern of -xxx, like a -902 error.  

Use the InterBase Language Reference manual  to look up the error and the 
error message.

BDE:    Download the DBI Error checking utility from the BDE Technical Support 
             pages of the www.borland.com website.  Run the utility and type in the 
             error number,  the corresponding error message will be returned.

ODBC: Try consulting an ODBC reference for the error code.

Last Modified: 29-SEP-00