Command SET RELATION Foundation
Creates a relational link between two work areas.
SET RELATION TO [<cRelation1> | <xRecordID1> INTO <cAlias1> ;
[TAG <cTag1>] ] ;
[, [TO] <cRelation2> | <xRecordID2> INTO <cAlias2> ;
[TAG <cTag2>]...] ;
[ADDITIVE] [SELECT[IVE]]
The command SET RELATION TO defines links between the current work area and one or more other work areas. The dependent, or child, work areas are specified by the argument <cAlias>. The controlling, or parent, work area is the current work area. The relation synchronizes the data record pointers in the child work areas with the data pointer in the parent work area.
The synchronization of the record pointer in the child work areas occurs using the value <cRelation>. The child work areas are automatically searched for this value using DbSeek() whenever the record pointer in the parent work area moves. This requires that the controlling index in the child work area have an index expression returning values that correspond to <cRelation>. The setting of SOFTSEEK is ignored. If the value of <cRelation> is not found in the controlling index of the child work area, the record pointer in the child work area is positioned after the last record and the function Eof() returns the value .T. (true) for this work area. If the value is found, the function Found() instead returns the value .T..
If no index is active in the child work area, synchronization occurs using the function DbGoto(), which attempts to set the record pointer in the child work area to the record ID corresponding with the value of <xRecordID>.
The range for navigating the record pointer in the child work area can be restricted to a subset of records by specifying the SELECT option. In this case, only those records are accessible in the child work area where the link expression <cRelation> results in the same value for both work areas. When attempting to move the record pointer in the child work area outside this defined range, either Bof() or Eof() is set to .T. (true). In this way, a time consuming filter expression can be avoided.
SET RELATION TO .. SELECT is identical to SET RELATION TO, but it sets up a relational restriction on the child work area at the same time the relation is set up. This means that whenever you select the child work area, only the records related to the current parent record will be visible.
Notes
It is possible to use scopes and filters when operating on the child area even if the child is part of a relational restriction set up with SET RELATION TO ... SELECT.
Using DbRSuspendSelect()/DbRResumeSelect() temporarily disables the relational restriction on the childarea to perform queries or else that require all records to become visible in the child work area.
The SELECT feature in conjunction with DbRSuspendSelect() allows straightforward handling of one-to-many and one-to-one relationships, and makes it possible the first time to setup a datamodel once at application startup. This, in turn, makes the database kernel working more like a relational database system.
Relations cost no runtime when navigating on the parent, only when the child-area is accessed the relational rules are applied. Different parents are allowed, the last parent navigation determines the relational restriction on the child area (last-come first serve).
The functions DbSetRelation() and DbClearRelation() are the functional equivalents of the command SET RELATION TO.
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.