Additional Relationship Information

The relationship data set technique allows additional information about the relationship between two data sets to be conveniently represented. Links and manual subsets, in contrast, cannot provide this function. The utility of this function can be illustrated using the preceding product structure database as an example.

In a manufacturing operation, the subparts of a part are added to the part. It is desirable to give such operations identifying numbers (OPERNUM) so that they can be referred to conveniently and described.

A particular part number can be assembled in a composite part more than once in a particular one-level-down parts list (for example, at two different operations). For this and other reasons, it is desirable to control parts lists by item number. The item number, ITEMNUM, uniquely identifies a line on the one-level-down parts list of a composite part. One-level-down parts lists are printed in item number order.

To avoid storing multiple parts list records for parts that appear several times in the ~one-level-down parts list of composite parts, and to handle nondiscrete parts such as liquids, it is desirable to have a quantity field in the parts list record. This field indicates the quantity of the subpart which goes in the composite part.

The product structure of a product can evolve over time. However, it is usually desirable to use up most or all of the parts in stock before commencing to manufacture newer versions of the product. For this and other reasons, it is desirable to maintain a history of the product structure in the database. This can be done by introducing the concept of build level.

The build level is an integer which starts at one and increases by one every time a composite part is changed. (This avoids the need to change the part number.) In this instance, the assumption is made that 999 is effectively infinity for the build level. Changes to the one-level-down parts list of a composite part are made by adding a new part beginning with a particular build level or by deleting a part after a certain build level. Let the first build level at which a subpart exists in the composite part be called BLDLEVIN, and let the last build level at which a subpart exists in the composite part be called BLDLEVOUT. By convention, when a part is first added to the one-level-down parts list of a composite part, it is considered to be there for all future build levels until such time as a change removes the part from the one-level-down parts list of the composite part. Therefore, the first time a subpart is added to the one-level-down parts list of a composite part, its BLDLEVOUT equals 999.

A DASDL description for the product structure extended to incorporate the preceding concepts is as follows:

PARTS RANDOM DATA SET
    (
     PARTNUM        NUMBER(8);
     BUILDLEVEL     NUMBER(3); % CURRENT I. E. LATEST
                               % BUILD LEVEL OF THIS
                               % PART
     DESCRIPTION    ALPHA(24);
    ) VERIFY PARTNUM>0;
PARTSKEY ACCESS TO PARTS KEY(PARTNUM) MODULUS 1500;
PARTSLIST DATA SET
    (
     COMPARTNUM     NUMBER(8); % COMPOSITE PART NUMBER
     SUBPARTNUM     NUMBER(8); % SUBPART PART NUMBER
     SUBPARTBLDLEV  NUMBER(3); % BUILD LEVEL OF SUBPART
     ITEMNUM        NUMBER(3); % LINE ITEM NUMBER OF
                               % THIS SUBPART
                               % ON THE ONE LEVEL
                               % DOWN PARTS LIST OF THE
                               % COMPOSITE PART
     QUANTITY       REAL;      % AMOUNT OR NUMBER OF
                               % THIS SUBPART IN THE
                               % COMPOSITE PART
     BLDLEVIN       NUMBER(3); % FIRST BUILD LEVEL OF
                               % THE COMPOSITE PART
                               % WHICH INCLUDES THIS
                               % SUBPART
     BLDLEVOUT      NUMBER(3); % LAST BUILD LEVEL OF
                               % THE COMPOSITE PART
                               % WHICH INCLUDES THIS
                               % SUBPART
     OPERNUM        NUMBER(3); % NUMBER OF THE
                               % MANUFACTURING
                               % OPERATION AT
                               % WHICH THIS
                               % SUBPART IS ASSEMBLED
                               % INTO THE COMPOSITE
                               % PART
    ) VERIFY BLDLEVIN LEQ BLDLEVOUT AND
          COMPARTNUM*SUBPARTNUM > 0;
EXPITEMSET SET OF PARTSLIST
     KEY(COMPARTNUM, ITEMNUM, BLDLEVOUT DESCENDING)
     DATA(BLDLEVIN);
EXPOPERSET SET OF PARTSLIST
     KEY(COMPARTNUM, OPERNUM, ITEMNUM,
     BLDLEVOUT DESCENDING)
     DATA(BLDLEVIN);
WUSET SET OF PARTSLIST
     KEY(SUBPARTNUM, COMPARTNUM, ITEMNUM,
      BLDLEVOUT DESCENDING)
     ;
OPERATIONS DATA SET
    (
     OPERNUM        NUMBER(3);
     COMPARTNUM     NUMBER(8); % NUM OF COMPOSITE PART
                               % BEING ASSEMBLED
    ) VERIFY OPERNUM*COMPARTNUM > 0;
OPERSET SET OF OPERATIONS KEY(COMPARTNUM, OPERNUM);

In anticipation that most parts explosions are done on more recent build levels, BLDLEVOUT is made a descending item in the keys of the sets against the PARTSLIST data set. BLDLEVIN is included as data in key to test the parts list record for inclusion in the explosion procedure without retrieving the actual record in the PARTSLIST data set. (Values of key data items do not affect the order in which the keys are stored in the index.) These two techniques increase the efficiency of the parts explosion procedure. The following procedure gives the full level parts explosion of a given part at a particular build level:

PROCEDURE ITEMEXPLODE(PARTNUM, BUILDLEVEL, LEVEL);
     VALUE PARTNUM, BUILDLEVEL, LEVEL;
     REAL PARTNUM, BUILDLEVEL, LEVEL;
BEGIN
     BOOLEAN RSLT;
     REAL ITEMNUM,SUBPARTNUM,SUBPARTBLDLEV,
     BLDLEVIN,BLDLEVOUT;
     FIND PARTKEY AT PARTNUM=PARTNUM;
     [PROCESS PARTS RECORD.]
     FIND KEY OF FIRST EXPITEMSET AT
          COMPARTNUM=PARTNUM  : RSLT;
     WHILE NOT RSLT DO
     BEGIN
          GET PARTSLIST
               (ITEMNUM : = ITEMNUM
               ,BLDLEVOUT : =BLDLEVOUT
               ,BLDLEVIN : = BLDLEVIN
               );
          IF BLDLEVOUT GEQ BUILDLEVEL THEN
          BEGIN
               IF BLDLEVIN LEQ BUILDLEVEL THEN
               BEGIN
                    FIND EXPITEMSET;
                    GET PARTSLIST
                         (SUBPARTNUM : = SUBPARTNUM
                          ,SUBPARTBLDLEV :
                           = SUBPARTBLDLEV);
                     ITEMEXPLODE(SUBPARTNUM,
                           SUBPARTBLDLEV,
                          LEVEL+1);
                     % NOTE: EXPITEMSET PATH HAS BEEN
                     % CHANGED BY RECURSIVE CALL.
                     % RESTORE PATH AND SKIP EARLIER
                     % BUILD LEVELS OF THIS ITEM.
                     FIND KEY OF FIRST EXPITEMSET AT
                          COMPARTNUM=PARTNUM AND
                          ITEMNUM>ITEMNUM  : RSLT;
                END ELSE  % IGNORE‑TOO RECENT
                     FIND KEY OF NEXT EXPITEMSET AT
                          COMPARTNUM=PARTNUM : RSLT;
           END ELSE
                % SKIP EARLIER BUILD LEVELS OF THIS ITEM
                FIND KEY OF NEXT EXPITEMSET AT
                     COMPARTNUM=PARTNUM AND
                     ITEMNUM>ITEMNUM  : RSLT;
      END;
      IF REAL(RSLT).DMERROR NEQ NOTFOUND THEN
           DMTERMINATE(RSLT);
 END ITEMEXPLODE;

The implosion procedure is for the latest build level of all parts only. That is, only parts list records with BLDLEVOUT equals 999 are included. The implosion cannot be performed at a specific build level in the same manner as the explosion. The implosion procedure can be written as follows:

PROCEDURE IMPLODE(PARTNUM, LEVEL);
     VALUE PARTNUM, LEVEL;
     REAL PARTNUM, LEVEL;
BEGIN
     BOOLEAN, RSLT;
     REAL BLDLEVOUT, HIGHERPARTNUM, ITEMNUM;
     FIND PARTKEY AT PARTNUM=PARTNUM;
     [PROCESS PARTS RECORD.]
     FIND KEY OF FIRST WUSET AT
          SUBPARTNUM=PARTNUM  : RSLT;
     WHILE NOT RSLT DO
     BEGIN
          GET PARTSLIST
               (HIGHERPARTNUM : =COMPARTNUM
               ,ITEMNUM : = ITEMNUM
               ,BLDLEVOUT : = BLDLEVOUT
               );
          IF BLDLEVOUT=999 THEN
          BEGIN
               [FIND WUSET IF DESIRE TO PROCESS
                    PARTSLIST RECORD.]
               IMPLODE(HIGHERPARTNUM, LEVEL+1);
               % NOTE: RECURSIVE CALL HAS CHANGED
               % PATH OF WUSET.  RESTORE PATH AND
               % SKIP EARLIER BUILD LEVELS.
               FIND KEY OF FIRST WUSET AT
                    SUBPARTNUM=PARTNUM AND
                    COMPARTNUM=HIGHERPARTNUM AND
                    ITEMNUMBER>ITEMNUMBER  : RSLT;
          END ELSE
               % SKIP EARLIER BUILD LEVELS
               FIND KEY OF NEXT WUSET AT
                    SUBPARTNUM=PARTNUM AND
                    COMPARTNUM=HIGHERPARTNUM AND
                    ITEMNUM>ITEMNUM  : RSLT;
     END;
     IF REAL(RSLT).DMERROR NEQ NOTFOUND THEN
          DMTERMINATE(RSLT);
END IMPLODE;

The PARTSLIST data set illustrates how a relationship data set can hold additional information about the relationship between two records. Note that neither links nor manual subsets can accomplish this.