In this section: |
Fixed-format sequential, VSAM, or ISAM data sources can have repeating fields. Consider the following data structure:
A |
B |
C1 |
C2 |
C1 |
C2 |
Fields C1 and C2 repeat within this data record. C1 has an initial value, as does C2. C1 then provides a second value for that field, as does C2. Thus, there are two values for fields C1 and C2 for every one value for fields A and B.
The number of times C1 and C2 occur does not have to be fixed. It can depend on the value of a counter field. Suppose field B is this counter field. In the case shown above, the value of field B is 2, since C1 and C2 occur twice. The value of field B in the next record can be 7, 1, 0, or any other number you choose, and fields C1 and C2 occur that number of times.
The number of times fields C1 and C2 occur can also be variable. In this case, everything after fields A and B is assumed to be a series of C1s and C2s, alternating to the end of the record.
Describe these multiply occurring fields by placing them in a separate segment. Fields A and B are placed in the root segment. Fields C1 and C2, which occur multiply in relation to A and B, are placed in a descendant segment. You use an additional segment attribute, the OCCURS attribute, to specify that these segments represent multiply occurring fields. In certain cases, you may also need a second attribute, called the POSITION attribute.
How to: |
The OCCURS attribute is an optional segment attribute used to describe records containing repeating fields or groups of fields. Define such records by describing the singly occurring fields in one segment, and the multiply occurring fields in a descendant segment. The OCCURS attribute appears in the declaration for the descendant segment.
You can have several sets of repeating fields in your data structure. Describe each of these sets of fields as a separate segment in your data source description. Sets of repeating fields can be divided into two basic types: parallel and nested.
OCCURS = occurstype
Possible values for occurstype are:
Is an integer value showing the number of occurrences (from 1 to 4095).
Names a field in the parent segment or a virtual field in an ancestor segment whose integer value contains the number of occurrences of the descendant segment. Note that if you use a virtual field as the OCCURS value, it cannot be redefined inside or outside of the Master File.
Indicates that the number of occurrences varies from record to record. The number of occurrences is computed from the record length (for example, if the field lengths for the segment add up to 40, and 120 characters are read in, it means there are three occurrences).
Place the OCCURS attribute in your segment declaration after the PARENT attribute.
When different types of records are combined in one data source, each record type can contain only one segment defined as OCCURS=VARIABLE. It may have OCCURS descendants (if it contains a nested group), but it may not be followed by any other segment with the same parent. There can be no other segments to its right in the hierarchical data structure. This restriction is necessary to ensure that data in the record is interpreted unambiguously.
Consider the following simple data structure:
A |
B |
C1 |
C2 |
C1 |
C2 |
You have two occurrences of fields C1 and C2 for every one occurrence of fields A and B. Thus, to describe this data source, you place fields A and B in the root segment, and fields C1 and C2 in a descendant segment, as shown here:
Describe this data source as follows:
FILENAME = EXAMPLE1, SUFFIX = FIX, $ SEGNAME = ONE, SEGTYPE=S0, $ FIELDNAME = A, ALIAS=, USAGE = A2, ACTUAL = A2, $ FIELDNAME = B, ALIAS=, USAGE = A1, ACTUAL = A1, $ SEGNAME = TWO, PARENT = ONE, OCCURS = 2, SEGTYPE=S0, $ FIELDNAME = C1, ALIAS=, USAGE = I4, ACTUAL = I2, $ FIELDNAME = C2, ALIAS=, USAGE = I4, ACTUAL = I2, $
Parallel sets of repeating fields are those that have nothing to do with one another (that is, they have no parent-child or logical relationship). Consider the following data structure:
A1 |
A2 |
B1 |
B2 |
B1 |
B2 |
C1 |
C2 |
C1 |
C2 |
C1 |
C2 |
In this example, fields B1 and B2 and fields C1 and C2 repeat within the record. The number of times that fields B1 and B2 occur has nothing to do with the number of times fields C1 and C2 occur. Fields B1 and B2 and fields C1 and C2 are parallel sets of repeating fields. They should be described in the data source description as children of the same parent, the segment that contains fields A1 and A2.
The following data structure reflects their relationship:
Nested sets of repeating fields are those whose occurrence depends on one another in some way. Consider the following data structure:
A1 |
A2 |
B1 |
B2 |
C1 |
C1 |
B1 |
B2 |
C1 |
C1 |
C1 |
In this example, field C1 only occurs after fields B1 and B2 occur once. It occurs varying numbers of times, recorded by a counter field, B2. There is not a set of occurrences of C1 which is not preceded by an occurrence of fields B1 and B2. Fields B1, B2, and C1 are a nested set of repeating fields.
These repeating fields can be represented by the following data structure:
Since field C1 repeats with relation to fields B1 and B2, which repeat in relation to fields A1 and A2, field C1 is described as a separate, descendant segment of Segment TWO, which is in turn a descendant of Segment ONE.
The following data structure contains both nested and parallel sets of repeating fields.
A 1 |
A 2 |
B 1 |
B 2 |
C 1 |
C 1 |
C 1 |
B 1 |
B 2 |
C 1 |
C 1 |
C 1 |
C 1 |
D 1 |
D 1 |
E 1 |
E 1 |
E 1 |
E 1 |
It produces the following data structure:
Describe this data source as follows. Notice that the assignment of the PARENT attributes shows you how the occurrences are nested.
FILENAME = EXAMPLE3, SUFFIX = FIX,$ SEGNAME = ONE, SEGTYPE=S0,$ FIELDNAME = A1 ,ALIAS= ,ACTUAL = A1 ,USAGE = A1 ,$ FIELDNAME = A2 ,ALIAS= ,ACTUAL = I1 ,USAGE = I1 ,$ SEGNAME = TWO, SEGTYPE=S0, PARENT = ONE, OCCURS = 2 ,$ FIELDNAME = B1 ,ALIAS= ,ACTUAL = A15 ,USAGE = A15 ,$ FIELDNAME = B2 ,ALIAS= ,ACTUAL = I1 ,USAGE = I1 ,$ SEGNAME = THREE, SEGTYPE=S0, PARENT = TWO, OCCURS = B2 ,$ FIELDNAME = C1 ,ALIAS= ,ACTUAL = A25 ,USAGE = A25 ,$ SEGNAME = FOUR, SEGTYPE=S0, PARENT = ONE, OCCURS = A2 ,$ FIELDNAME = D1 ,ALIAS= ,ACTUAL = A15 ,USAGE = A15 ,$ SEGNAME = FIVE, SEGTYPE=S0, PARENT = ONE, OCCURS = VARIABLE,$ FIELDNAME = E1 ,ALIAS= ,ACTUAL = A5 ,USAGE = A5 ,$
Note:
How to: |
The POSITION attribute is an optional attribute used to describe a structure in which multiply occurring fields with an established number of occurrences are located in the middle of the record. You describe the data source as a hierarchical structure, made up of a parent segment and at least one child segment that contains the multiply occurring fields. The parent segment is made up of whatever singly occurring fields are in the record, as well as one or more alphanumeric fields that appear where the multiply occurring fields appear in the record. The alphanumeric field may be a dummy field that is the exact length of the combined multiply occurring fields. For example, if you have four occurrences of an eight-character field, the length of the field in the parent segment is 32 characters.
You can also use the POSITION attribute to redescribe fields with SEGTYPE=U. For more information, see Redefining a Field in a Non-FOCUS Data Source.
The POSITION attribute is described in the child segment. It gives the name of the field in the parent segment that specifies the starting position and overall length of the multiply occurring fields. The syntax of the POSITION attribute is
POSITION = fieldname
where:
Is the name of the field in the parent segment that defines the starting position of the multiple field occurrences.
Consider the following data structure:
A1 |
Q1 |
Q1 |
Q1 |
Q1 |
A2 |
A3 |
A4 |
In this example, field Q1 repeats four times in the middle of the record. When you describe this structure, you specify a field or fields that occupy the position of the four Q1 fields in the record. You then assign the actual Q1 fields to a multiply occurring descendant segment. The POSITION attribute, specified in the descendant segment, gives the name of the field in the parent segment that identifies the starting position and overall length of the Q fields.
Use the following Master File to describe this structure:
FILENAME = EXAMPLE3, SUFFIX = FIX,$ SEGNAME = ONE, SEGTYPE=S0,$ FIELDNAME = A1 ,ALIAS= ,USAGE = A14 ,ACTUAL = A14 ,$ FIELDNAME = QFIL ,ALIAS= ,USAGE = A32 ,ACTUAL = A32 ,$ FIELDNAME = A2 ,ALIAS= ,USAGE = I2 ,ACTUAL = I2 ,$ FIELDNAME = A3 ,ALIAS= ,USAGE = A10 ,ACTUAL = A10 ,$ FIELDNAME = A4 ,ALIAS= ,USAGE = A15 ,ACTUAL = A15 ,$ SEGNAME = TWO, SEGTYPE=S0, PARENT = ONE, POSITION = QFIL, OCCURS = 4 ,$ FIELDNAME = Q1 ,ALIAS= ,USAGE = D8 ,ACTUAL = D8 ,$
This produces the following structure:
If the total length of the multiply occurring fields is longer than 4095, you can use a filler field after the dummy field to make up the remaining length. This is required, because the format of an alphanumeric field cannot exceed 4095 bytes.
Notice that this structure works only if you have a fixed number of occurrences of the repeating field. This means the OCCURS attribute of the descendant segment must be of the type OCCURS=n. OCCURS=fieldname or OCCURS=VARIABLE does not work.
How to: |
In an OCCURS segment, the order of the data may be significant. For example, the values may represent monthly or quarterly data, but the record itself may not explicitly specify the month or quarter to which the data applies.
To associate a sequence number with each occurrence of the field, you may define an internal counter field in any OCCURS segment. A value is automatically supplied that defines the sequence number of each repeating group.
The syntax rules for an ORDER field are:
Order values are 1, 2, 3, and so on, within each occurrence of the segment. The value is assigned prior to any selection tests that might accept or reject the record, and so it can be used in a selection test.
The following declaration assigns ACT_MONTH as the ORDER field:
FIELD = ACT_MONTH, ALIAS = ORDER, USAGE = I2MT, ACTUAL = I4, $
The following WHERE test obtains data for only the month of June:
SUM AMOUNT... WHERE ACT_MONTH IS 6
The ORDER field is a virtual field used internally. It does not alter the logical record length (LRECL) of the data source being accessed.