Question:
When working with any IBX dataset component, why doesn't RecordCount return then number of records in my table on the server?

Answer:
The BDE called FetchAll before calling RecordCount, IBX datasets do not. Call TDataSet.FetchAll before using TDataSet.RecordCount. FetchAll actually downloads all the records locally and counts them, for large tables and result sets, this can be undesirable. A faster, server side way, of accomplishing the same task is to use two select statements:

IBQuery1.SQL.Clear;
IBQuery1.SQL.Add('select count(ANYFIELD) FROM YOURTABLE');
IBQuery1.Open;

You can access the RecordCount by

IBQuery1.FieldByName('COUNT').AsInteger;

Question:
I just installed Delphi using a Read/Write CD drive. It took an unusually long time to install, and now it doesn't run - it just gives an error message. How can I fix this problem?

Answer:
It appears that some Read-Write CD Drives don't work quite right when trying to install Delphi. They may takse an unusually long time to install, with the CD-ROM 'clicking' as it does a reading-stopping-reading process. There is a known problem with HyVal IDE drive causing this problem.

The solution is to install a new driver for the RW-CD that hopefully doesn't have the problem.

Or, you can try installing from a traditional CD-ROM drive instead of the RW-Drive. If you are on a network, another alternative is to 'Map' someone else's CD-ROM drive and install Delphi from this mapped drive.

Question:
I have a TThread object which may raise an exception in the Execute procedure. When an exception is raised, I want to be able to show that exception to the end user. How do I go about doing this in the most efficient way?

Answer:
With a TThread object, if you don't catch an exception in the Execute procedure of a TThread, you may get access violations. The Delphi IDE may break fine on the exception, but often when the application is run outside of the IDE you get an "Application error has occurred" exception and your application stops running.

If you don't care about showing the end user that an exception occurred, you can simply wrap your Execute procedure with a try..finally block such as:
procedure TMyThread.Execute;
begin
try
// Do your thread stuff here
except // Eat all exceptions
end;
end;
Quite often, this isn't the best solution and you will want to show the message to the end user, or allow your application to further process the message.

The easiest way to do this, is to add an Exception object to your TThread class, and call the appropriate handler based on the type of exception. Here is an example of how to do this. The project consists of one form with a Button placed on it:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyThread = class(TThread)
private
FException: Exception;
procedure DoHandleException;
protected
procedure Execute; override;
procedure HandleException; virtual;
public
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TMyThread.DoHandleException;
begin
// Cancel the mouse capture
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
// Now actually show the exception
if FException is Exception then
Application.ShowException(FException)
else
SysUtils.ShowException(FException, nil);
end;

procedure TMyThread.Execute;
begin
FException := nil;
try
// raise an Exception
raise Exception.Create('I raised an exception');
except
HandleException;
end;
end;

procedure TMyThread.HandleException;
begin
// This function is virtual so you can override it
// and add your own functionality.
FException := Exception(ExceptObject);
try
// Don't show EAbort messages
if not (FException is EAbort) then
Synchronize(DoHandleException);
finally
FException := nil;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
// Create an instance of the TMyThread
with TMyThread.Create(True) do
begin
FreeOnTerminate := True;
Resume;
end;
end;

end.

Question:
Why am I getting the error "Non-blob column in table required to perform operation" when trying to access a BLOB or CLOB with Oracle 8?

Answer:
TTables and Live TQueries may not allow access to Oracle 8 CLOB or BLOB fields when the user has a role of DBA, EXP_FULL_DATABASE, IMP_FULL_DATABASE or SELECT_CATALOG_ROLE especially if the table was created by a user without one of these roles. Users with these roles return LOB indexes in the list of index definitions because the BDE queries a different set of system views compared to users without these roles.

These LOB indexes do not have corresponding column definitions. The error will occur when the primary key has a name that causes it to be sorted after the LOB indexes in the result set.


The error does not occur for users with roles other than DBA, EXP_FULL_DATABASE, IMP_FULL_DATABASE or SELECT_CATALOG_ROLE.

To determine what roles a the current user has query SYS.USER_ROLE_PRIVS.

To determine what roles all users have been granted query SYS.DBA_ROLE_PRIVS when logged in as a user with a GRANTED role of DBA, EXP_FULL_DATABASE, IMP_FULL_DATABASE or SELECT_CATALOG_ROLE.



QUESTION:

What causes BDE Error 8712 "Could not find object" when accessing MS SQL Server 7 table? Other Symptoms could be columns not appearing or blank.

ANSWER:

MS SQL Server 7 introduces new field types called NVARCHAR, NCHAR and NTEXT. These types represent Unicode data and are not supported by the BDE.

The workaround is to change these field types to VARCHAR or TEXT.


Please note there are no ODBC drivers which have been certified by Borland which support MSSQL Server 7, only up to MSSQL Server 6.5 (see the Readme.txt file).

We recommend using the ADO components available with Delphi 5 to connect to MS SQL Server 7.

Question:
How do I query a Paradox or dBASE table using Day-Month-Year instead of Month-Day-Year?

Answer:
The local SQL engine uses the separator to decide the format of a date. A / is interpreted as M/D/Y. A . is interpreted as D.M.Y.

Examples:

11/1/99 is November 1, 1999.

11.1.99 is January 11, 1999.

QUESTION:
Can I execute an Oracle User Function via a Stored Proc?

ANSWER:
Yes. There are a number of things to remember about this process:

Functions cannot be dragged and dropped from SQL Explorer like procedures can.

The first parameter in the parameter list (parameter 0) is the return value of the function. The DataType should match the return data type of your function. The name must be Result. The ParamType must be ptResult.

If you are creating a TStoredProc dynamically Prepare does not automatically load function parameters with BDE 5.10 like it did with previously with older versions of the BDE. You'll have to use TStoredProc.Params.CreateParam to add all parameters to your TStoredProc.

Question:
I'm calling a StoredProc on MSSQL or Sybase that returns a result set and other other output parameters. Why do I never get any values in my output parameters?

Answer:
For MSSQL and Sybase, parameters are not returned until you go to the end of the result set. You must execute code similar to the following:

with StoredProc1 do
begin
Open;
Last;
GetResults;
//Retrieve output parameters here
end;

For more information on GetResults see TStoredProc.GetResults in Delphi or C++ Builder Help.

Question:
When I execute TIBQuery.RecordCount why doesn't it give me a count of all my records in my Query?

Answer:
TIBQuery.RecordCount does the same thing as TIBSQL.RecordCount. Here is what Help says for TIBSQL.RecordCount:

Use the RecordCount property to see how many records are returned by a query. If the result set is to return 100 rows, RecordCount will only be 100 after all the records have been visited. That is, after looking at the first record, RecordCount is 1, and so forth.

The reason RecordCount operates in this fashion is calculating all the records in a dataset is potentially time consuming operation as it would require scanning through the entire dataset. The most efficient way to calculate the number of records in a dataset is to execute a SELECT COUNT(*) statement.

Question:
I am attempting to add data to my Paradox table but I'm getting the Error "Table is Full". What is the cause of this and how can I add more records?

Answer:
Paradox tables have a block size which determines the maximum record size for a table and the table's maximum size. By default tables have a block size of 4K. Regardless of the block size, tables can have a maximum of 64K blocks. This means by default a table can grow to 256 MB.

You can increase the block size of a table in 1 of two ways.
Run BDE Admin and change the block size for the Paradox driver to a revised number. Legal block sizes are 1024, 2048, 4096, 16384 and 32768. If your block size is larger then 4096 then you must also change level to be at least 5. Finally, create a new table and batchmove your data from your old table to your new table
It is possible to change the block size of an existing table by calling dbiDoRestucture. For an example see www.borland.com/devsupport/bde/files/pxrest.zip

Unique Indexes in dBASE tables have historically operated differently than unique indexes in other databases. Most or all other databases use unique indexes to prevent duplicate entries from being placed in a table. The way dBASE tables have worked is not to prevent duplicate entries from being entered in a table, but to only display unique values in the index when the index is selected.

One side effect of this technique is dealing with deleted records. If you delete the record which displays when the unique index is chosen, no values for the record deleted will be displayed even though they exist in the database until the database is packed.

When Visual dBASE 7 was released it offered a new way to create unique indexes. It added the new option of creating unique indexes which are distinct. Such indexes operate in the manner that most other database operate in that duplicate values are prohibited.

Visual dBASE can create and use either style of index. Delphi and C++ Builder can use either style index, but can only create distinct unique indexes. So, if you need to create unique indexes which are not distinct you must use Visual dBASE to create them.

Visual dBASE is owned by dBASE2000. For additional information on Visual dBASE see www.dbase200.com

Question: I have a procedure (or a function) in my Oracle package, but when I get a list of stored procedure names for my TStoredProc it is not listed. Why is this?

Answer: Only procedure names listed in sys.all_objects are listed, because returning these results is a fast query. To get a list of procedures in packages, each package would require parsing which would be a slow operation.

Q. Is Oracle client 8.0.5 supported by the BDE Native driver?

A. No. Due to blob inconsistencies that QA and R&D encountered with this client it is not certified. Version 8.0.4 and 8.1.5 are supported.

"Data Truncated" is an common error that occurs when using the 8.0.5 Client.

Question:
When I open my TQuery, why am I getting an "Operation Not Applicable Error" when my TQuery returns no records?

Answer:
If you have Unidirectional set to True for your TQuery this error will occur. If you think you may be in this condition, run a select count(*) query to determine the number of records returned from your Query before running the TQuery.

Note: in Delphi 2 and 3 this condition does not occur.

Q. I notice that as I scroll my TQuery forward more and more memory is used. How do I prevent this?

A. If your TQuery is forward only cursor, then setting unidirectional to true will resolve the problem.

Note that any memory used by the TQuery is freed when the TQuery is closed.

CLICK TO REGISTER