Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Useful M/D/D/D/D/D model available for free.

Status
Not open for further replies.

delphiman

Programmer
Dec 13, 2001
422
ZA

I have developed a unique (?) working model of a
Master/Detail/Detail/Detail/Detail/Detail (etc.)relationship which I am prepared
to download to anyone interested. Provided they can assist with a few REMAINING problems - listed below.

REQUIRED:
4 tables called PARENT, CHILD, GCHILD and GGCHILD wherein it is essential that the
first child (C_NO in CHILD) of each parent (P_NO in PARENT) MUST be numbered "1". As must
also be the case with the first grand-child (GC_NO in GCHILD) etc..

TWO PROBLEMS AT OUTSET

1.
I cannot develop such a relationship using .DB tables and TTable Object from the Delphi VCL as,
Whilst the Referential Integrity between tables are perfect for what I need, they do not
(to begin with) provide for more than a Master/Detail/Detail relationship - which is too
limiting for my needs.

2.
Whilst I can use .GDB tables and SQL (as an alternative) they do not overcome Problem 1 above
either - if one follows the normal (?) approach.

In fact then I am worse off. In that I cannot even have two children (in a tbl CHILD) EACH numbered "1" (in a field C_NO) for each of two parents (in fields P_NO) in a tblPARENT - as is at least possible with the former option. Because C_NO must (of necessity) be a Unique field
in order that GC_NO (from tbl GPARENT) can relate to it in the .GDB table.

THE SOLUTION

1.
Using a .GDB Table and purely to provide an Index and prevent key-violations in each table I have a field CID_NO (for tbl CHILD), field GCID_NO (for tbl GCHILD), etc..

(At which point I might mention that the following will NOT work.

SELECT *
FROM CHILD t1, PARENT t2
WHERE t1,P_NO =: T2.P_NO

As it merely serves to provide ANY AND ALL records in (say) CHILD which have a P_NO in PARENT. In fact ALL them - regardless of the value of P_NO pointed to in PARENT at any given moment.

2.
I have an intermediate tbl TRNSFR (which must NEVER have more than ONE record) to which ALL the tables can easily relate as it has fields P_NO, C_NO, GC_NO GGC_NO.

3.
Using the AfterScroll of the relevant table the value of P_NO (of PARENT) C_NO (of CHILD, etc.) can be posted to TRNSFR the moment the pointer moves.

4.
NOW the following provides the required result:
(Bearing in mind that I am involved with Delphi 6, Interbase 6 and the ThinClient of a 3-Tier application.)

4.1
procedure TParentDM.IBdsChildAfterScroll(DataSet: TDataSet);
begin
with ParentDM.IBdsTrnsfr do
begin
ParentDM.IBdsTrnsfr.Active := True;
if ParentDM.IBdsTrnsfr.state in dsEditModes then
else
ParentDM.IBdsTrnsfr.edit;
ParentDM.IBdsTrnsfrC_NO.value := ParentDM.IBdsCHILDC_NO.value;
ParentDM.IBdsTrnsfr.ApplyUpdates;
end;
end;

4.2 In ModifySQL of IBDataSet I have

SELECT *
FROM CHILD t1,TRNSFR t2
WHERE t1.P_NO = t2.P_NO

(From which the reason for never having more than ONE record in TRNSFR becomes obvious.)


PROVIDED THAT one has a TButton EventHandler

procedure TfrmFather.btnUpdChildClick(Sender: TObject);
begin
ParentDM.IBdsTrnsfr.ApplyUpdates;
ParentDM.IBFatherDataSet.ApplyUpdates;
ParentDM.IBdsChild.ApplyUpdates;
end;

BECAUSE the desired effect from 4.1 is delayed.
(i.e. AfterScroll of having moved TO (say) P_NO 2 only becomes evident upon doing an AfterScroll a SECOND time - to anywhere.)

And accordignly one HAS TO rely on the TButton above to UpDate the movement of the pointer in PARENT.


REMAINING PROBLEMS.

1.
Overcoming the delay-effect mentioned above. This creating
reliance on the TButton. Instead of it happening automatically with AfterScroll - the FIRST time.

2.
If (to overcome 1. above) the statement (below) from the TButton EventHandler is included to follow the code in 4.1 above (where it belongs) I get the following exception.

ParentDM.IBdsChild.ApplyUpdates;

'IBdsChild: Cannot perform this operation on a closed dataset'

3.
A Delete of a record in (say) CHILD which still has related records in GCHILD etc.. should be prevented.

Any takers. :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top