Board index » delphi » Help with Paradox 5 table - Cascade Deletes don't seem to work

Help with Paradox 5 table - Cascade Deletes don't seem to work

Hi there,

I have written a delphi 3 App that works with a master-detail paradox 5
dataset.

I have a master table, with 3 detail tables (all paradox5 tables).  I have
used the referential integrity tool of the database desktop to define the
relations, and have assigned the 3 details tables all as being cascade.

Yet when I try to delete a record in the master table, I get an error, and
I have to delete the child records in each of my detail tables in order to
delete the parent.   Isn't this the point of cascaded deletes or am I just
stupid?

Any help would be appreciated here.  I am no wiz at either Delphi or
Paradox.

--
please remove the _nospamplz from my userid when replying directly

 

Re:Help with Paradox 5 table - Cascade Deletes don't seem to work


On 29 Jul 1999 14:26:08 GMT, "Serge Beaulieu" <sergeb_nospam...@fundy.net>
wrote:

Quote
>I have written a delphi 3 App that works with a master-detail paradox 5
>dataset.

>I have a master table, with 3 detail tables (all paradox5 tables).  I have
>used the referential integrity tool of the database desktop to define the
>relations, and have assigned the 3 details tables all as being cascade.

>Yet when I try to delete a record in the master table, I get an error, and
>I have to delete the child records in each of my detail tables in order to
>delete the parent.   Isn't this the point of cascaded deletes or am I just
>stupid?

Paradox tables offer a Referential Integrity feature. This feature prevents
adding records to a child table for which there is no matching record in
the parent table. It will also cause the key field(s) in the child table to
be changed when the corresponding key field(s) in the parent are changed
(commonly referred to as a cascading update). These events occur
automatically, requiring no intervention by a Delphi application using
these tables. However, the Paradox Referential Integrity feature will not
accommodate cascading deletes. That is, Delphi will not allow you to delete
a record in the parent table while matching records exist in the child
table. This would make "orphans" of the child records, losing referential
integrity. Delphi raises an exception when an attempt is made to delete
such a parent record.

To effect a cascading delete requires that the deletion of the matching
child records be deleted programmatically -- before the parent record is
deleted. In a Delphi application, this is done by interrupting the process
of deleting the record in the parent table, deleting the matching records
in the child table (if there are any), and then continuing with the
deletion of the parent record.

A record in a table is deleted by a call to the Delete method of the TTable
component, which deletes the current record in the associated table.
Interrupting the this process to first perform some other operations is a
matter creating a procedure associated with the BeforeDelete event of the
TTable. Any commands in a BeforeDelete event procedure are executed before
the call actually goes out from the application to the Borland Database
Engine (BDE) to physically remove the record from the table file.

To handle the deletion of one or more child records, in a BeforeDelete
event procedure the Delete method for the TTable representing the child
table is called in a loop. The loop is based on the condition of the record
pointer in the table not being positioned at the end of the data set, as
indicated by the Eof method of the TTable. This also accounts for there
being no child records at all matching the parent record to be deleted: if
there are no matching records, the record pointer will already be at the
end of the data set, the loop condition will evaluate to False, and the
Delete method in the loop nevers gets executed.

  procedure TForm1.Table1BeforeDelete(DataSet: TDataset);
  begin
    with Table2 do begin
      DisableControls;
      First;
      while not Eof do
        Delete;
      EnableControls;
    end;
  end;

In the above example, the parent table is represented by the TTable
component Table1 and the child by Table2. The DisableControls and
EnableControls methods are used as a cosmetic measure to freeze any
data-aware components that might be displaying data from Table2 while the
records are being deleted. These two methods make the process visually
appear smoother, but are only optional and not essential to this process.
The Next method need not be called within this loop. This is because the
loop begins at the first record and, as each record is deleted, the record
that previously followed the deleted record moves up in the data set,
becoming both the first and the current record.

This example presumes that the parent and child tables are linked with a
Master-Detail relationship, as is typical for tables for which such
Referntial Integrity is configured. Linking the tables in this manner
results in only those records in the child table that match the current
record in the parent table being available. All other records in the child
table are made unavailable through the Master-Detail filtering. If the
tables are not so linked, there are two additional considerations that must
be accounted for when deleting the child records. The first is that a call
to the First method may or may not put the record pointer on a record that
matches the current record in the parent table. This necessitates using a
search method to manually move the record pointer to a matching record. The
second consideration affects the condition for the loop. Because records
other than those matching the current record in the parent table will be
accessible, the condition for the loop must check that each record is a
matching record before attempting to delete it. This checking is in
addition to querying the Eof method. Because the records will be ordered by
this key field (from a primary or secondary index), all of the matching
records will be contiguous. This leads to the given that, as soon as the
first non-matching record is reached, it can be assumed that all matching
records have been deleted. Thus, the previous example would be modified to:

  procedure TForm1.Table1BeforeDelete(DataSet: TDataset);
  begin
    with Table2 do begin
      DisableControls;
      FindKey([Table1.Fields[0].AsString])
      while (Fields[0].AsString = Table1.Fields[0].AsString) and
        (not Eof) do
        Delete;
      EnableControls;
    end;
  end;

In the above, it is the first field in the parent table (Table1) upon which
the Referential Integrity is based, and the first field in the child table
(Table2) against which matching is judged.

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
Steve Koterski         "Television is a medium because anything well done
Felton, CA             is rare."
                                                 -- Fred Allen (1894-1956)

Re:Help with Paradox 5 table - Cascade Deletes don't seem to work


H,

Serge Beaulieu <sergeb_nospam...@fundy.net> schrieb in im Newsbeitrag:
01bed9cd$92393ba0$e50a1...@default.reg2.health.nb.ca...
...

Quote
> Yet when I try to delete a record in the master table, I get an error, and
> I have to delete the child records in each of my detail tables in order to
> delete the parent.   Isn't this the point of cascaded deletes or am I just
> stupid?

It's the point, and you are not stupid - just a little bit out of
information :) Borland's Paradox engine does not support cascaded delete. It
don't work. No way. Basta.

Bye, Ralf

Other Threads