|
|
Line 1: |
Line 1: |
| <div class="toclimit-3">
| | #REDIRECT [[Processing multiply occurring fields and field groups]] |
| | |
| ==Overview==
| |
| <p>
| |
| A single field name that has different values can be stored repeatedly in a record. For example, the field <code>CHILD</code> in the record shown below is an example of a <b>multiply occurring field</b>:</p>
| |
| <p class="code">FATHER = JOHN DOE
| |
| CHILD = ELIZABETH
| |
| CHILD = ROBERT
| |
| </p>
| |
| <p>
| |
| Any field name except for the following types of fields can be present more than once in a record: </p>
| |
| <ul>
| |
| <li>A NUMERIC RANGE field </li>
| |
| <li>A sort key </li>
| |
| <li>A hash key </li>
| |
| </ul>
| |
|
| |
| <div id="FIELDGROUP overview"></div> <!-- This id referenced off the page, e.g., #REDIRECT on FIELDGROUP operations page-->
| |
| | |
| JOHN DOE might also have a medical record that recorded multiple surgeries, each of which is associated with a surgeon and a date. His record contains repeated instances of these three related fields:
| |
| <p class="code">SURGERY_TYPE
| |
| SURGEON
| |
| SURGERY_DATE </p>
| |
| | |
| As of version 7.5 of <var class="product">Model 204</var>, SOUL lets you define these fields as part of a "physical" <b>field group</b>, which means they are stored, retrieved, and updated as a single instance of, say, the <code>SURGERY</code> field group. You could define these fields as individual multiply occurring fields and group them logically in your SOUL code, but the physical field group structure has significant processing efficiencies.
| |
| | |
| Field groups may only be defined for records in files that have the <var>[[FILEORG parameter|FILEORG]]</var> parameter set to include <code>X'100'</code>. Information about how to define a field group is found in [[Field group design#Defining a field group|Defining a field group]].
| |
| | |
| ===Special processing for multiply occurring fields and field groups===
| |
| <p>
| |
| Certain SOUL statements operate differently on multiply occurring fields and field groups than on singly occurring fields. SOUL provides special statements and forms of statements that can be used with multiply occurring fields and field groups, notably including the <var>EACH</var> modifier and subscripts. SOUL also provides for the use of subscripted field references for accessing a particular occurrence of a multiply occurring field or field group.</p>
| |
| | |
| ==FIND statement==
| |
|
| |
| ===Retrieval by an exact occurrence value===
| |
|
| |
| ====Example 1====
| |
| <p>
| |
| Assume this sample record: </p>
| |
| <p class="code">FATHER = JOHN DOE
| |
| CHILD = ELIZABETH
| |
| CHILD = ROBERT
| |
| </p>
| |
| <p>
| |
| You can use either of these two statements to retrieve the record: </p>
| |
| <p class="code">FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| CHILD = ELIZABETH
| |
| END FIND
| |
|
| |
| FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| CHILD = ROBERT
| |
| END FIND
| |
| </p>
| |
|
| |
| ====Example 2====
| |
| <p>
| |
| The record is not retrieved by either of these statements:</p>
| |
| <p class="code">FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| CHILD = NOT ELIZABETH
| |
| END FIND
| |
|
| |
| FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| CHILD = NOT ROBERT
| |
| END FIND
| |
| </p>
| |
|
| |
| ===Multi-condition range retrievals===
| |
| <p>
| |
| You should pay special attention to the effect of multiply occurring fields on multi-condition range retrievals. Undesirable results can occur if a range search is specified for a multiply occurring field. For example: </p>
| |
| <p class="code">FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| CHILD IS AFTER KEN AND BEFORE PAUL
| |
| END FIND
| |
| </p>
| |
| <p>
| |
| retrieves the sample record even though neither child's name in the sample is between KEN and PAUL. <var class="product">Model 204</var> evaluates each condition of the FIND separately, then combines the results of each evaluation to build the set of records satisfying all conditions. The BETWEEN operator behaves exactly like any other multi-condition range retrieval when used on a multiply occurring field.</p>
| |
| <p>
| |
| If a range search must be performed on a multiply occurring field, use the IN RANGE clause of the FIND statement. Refer to [[Record retrievals#NUMERIC RANGE and ORDERED NUMERIC attributes|NUMERIC RANGE and ORDERED NUMERIC attributes]] for more information about the IN RANGE clause. Better code for the previous example is: </p>
| |
| <p class="code">FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| CHILD IS ALPHA IN RANGE
| |
| AFTER KEN AND BEFORE PAUL
| |
| END FIND
| |
| </p>
| |
|
| |
| ===Use of subscripts===
| |
| <p>
| |
| You cannot use subscripted references with the FIND statement. Refer to [[#Subscripts|Subscripts]] for more information about using subscripts with multiply occurring fields.</p>
| |
|
| |
| ==NOTE statement==
| |
|
| |
| ===Only first occurrence is noted===
| |
| <p>
| |
| The NOTE statement notes only the first occurrence of a multiply occurring field. For example, only the first occurrence of the field (CHILD = ELIZABETH) are noted by:</p>
| |
| <p class="code">KEEP.CHILD: NOTE CHILD
| |
| </p>
| |
|
| |
| ===Use of subscripts===
| |
| <p>
| |
| In order to note a particular occurrence of a multiply occurring field, the field name must be subscripted. Refer to the discussion of subscripts on [[#Subscripts|Subscripts]] for detailed information on subscripted field names and usage.</p>
| |
|
| |
| ==PRINT and PRINT n statements==
| |
|
| |
| ===PRINT statement output format===
| |
| <p>
| |
| The PRINT statement prints only the first occurrence of a field in a record. </p>
| |
| <p>
| |
| If there is more than one value of a field in a record, the special modifier, EACH, can be used in a PRINT statement to print out all the values on a single line, with a single space between values.</p>
| |
|
| |
| ====Example 1====
| |
| <p class="code">PRINT EACH INCIDENT
| |
| </p>
| |
| <p>
| |
| yields:</p>
| |
| <p class="output">T1 T2 T1 T3 T2 T1
| |
| </p>
| |
|
| |
| ====Example 2====
| |
| <p>
| |
| If the field is given a column position, as in:</p>
| |
| <p class="code">PRINT FULLNAME WITH EACH INCIDENT AT COLUMN 18
| |
| </p>
| |
| <p>
| |
| values are printed one to a line and positioned at the column specified. </p>
| |
| <p class="output">ABBOTT, GAIL H T1 -
| |
| T3 -
| |
| T1 -
| |
| T3 -
| |
| T2 -
| |
| T1
| |
| </p>
| |
|
| |
| ====Example 3====
| |
| <p>
| |
| A field cited in a PRINT statement after a multiply occurring field is printed on the same line as the last value of the multiply occurring field. If you change the PRINT statement in the sample request as here:</p>
| |
| <p class="code">PRINT FULLNAME WITH EACH INCIDENT AT COLUMN 18 -
| |
| WITH POLICY NO AT COLUMN 23 -
| |
| WITH STATE AT COLUMN 32
| |
| </p>
| |
| <p>
| |
| This output results:</p>
| |
| <p class="output">ABBOTT, GAIL H T1 -
| |
| T3 -
| |
| T1 -
| |
| T3 -
| |
| T2 -
| |
| T1 100340 CALIFORNIA
| |
| </p>
| |
| | |
| ===Use of subscripts===
| |
| <p>
| |
| See [[#PRINT statement|PRINT statement]] for a description of using PRINT with subscripts.</p>
| |
|
| |
| ===PRINT n statement===
| |
| <p>
| |
| Long fields, such as abstracts, evaluations, or statements of purpose, can be stored as a multiply occurring field. Each occurrence can contain as many as 255 characters. </p>
| |
|
| |
| ====Syntax====
| |
| <p>
| |
| You can use this PRINT statement to print such a field as a paragraph:</p>
| |
| <p class="syntax">PRINT <span class="term">n fieldname</span>
| |
| </p>
| |
| <p>
| |
| where <var class="term">n</var> must be a number less than 32,768.</p>
| |
|
| |
| ====Output format====
| |
| <p>
| |
| The <var>PRINT n</var> statement prints up to n lines of text, composed of all of the occurrences of the field concatenated in order. Nothing is inserted. At most, n lines are printed; any extra lines are ignored. </p>
| |
| <p>
| |
| Ordinarily, a PRINT statement that produces more than one line inserts a hyphen in the continuation column of the output device. Instead of using the continuation column, this form of PRINT attempts to end each line with a complete word delimited by spaces. If there is insufficient space to fit the last word on a line, the word is hyphenated arbitrarily and continued on the next line. </p>
| |
| <p>
| |
| The AT COLUMN and TO COLUMN clauses can be used to adjust the output to a narrower column. When used together with PRINT n, text is broken at word boundaries to fit within the column. The AT clause does not affect the first line, and the TO clause does not affect the last line (unless the line limit n is exceeded). This allows indenting. </p>
| |
| <p>
| |
| The AT or TO column options cannot accept negative numbers or numbers greater than 32767 for the column. </p>
| |
| <p>
| |
| Procedures containing PRINT statements with negative numbers or numbers greater than 32767 fail at compile time with the following counting error message:</p>
| |
| <p class="code">M204.0263: AT/TO MUST BE BETWEEN 1 AND 32767
| |
| </p>
| |
|
| |
| ====Example====
| |
| <p>
| |
| This example illustrates the use of the <var>PRINT n</var> statement.</p>
| |
| <p class="code">BEGIN
| |
| PRINT '1234567890123456'
| |
| STORE RECORD
| |
| TEXT = 'NOW IS THE T'
| |
| TEXT = 'IME FOR'
| |
| TEXT = ' ALL GOOD MEN TO'
| |
| ITEM = 1
| |
| END STORE
| |
| FD.REC: FIND ALL RECORDS FOR WHICH
| |
| ITEM = 1
| |
| END FIND
| |
| FOR 1 RECORD IN FD.REC
| |
|
| |
| PRINT.TEXT: PRINT <nowiki>''</nowiki> AT COLUMN 5 WITH 3 TEXT -
| |
| AT COLUMN 3 TO 16
| |
| END FOR
| |
| END
| |
| </p>
| |
| <p>
| |
| The output produced is:</p>
| |
| <p class="output">1234567890123456
| |
| NOW IS THE
| |
| TIME FOR ALL
| |
| GOOD MEN TO
| |
| </p>
| |
| <p>
| |
| The <code>PRINT.TEXT</code> statement concatenates a null value (two single quotes with no space between them) with the <var>PRINT n</var> form to indent the first line of text by using the location of the null value (column 5).</p>
| |
| <p>
| |
| Note that the printing stops short of column 16 to avoid truncating TIME and GOOD. </p>
| |
| | |
| ====Use with subscripts====
| |
| <p>
| |
| You cannot use subscripted references with the PRINT n statement. Refer to [[#Subscripts|Subscripts]] for more information about using subscripts with multiply occurring fields.</p>
| |
|
| |
| ==ADD, CHANGE, and DELETE statements==
| |
| <p>
| |
| The ADD and CHANGE statements, and both forms of the DELETE statement, are supported in remote file and scattered group contexts.</p>
| |
|
| |
| ===ADD statement===
| |
| <p>
| |
| The ADD statement places new occurrences of a field after existing occurrences. For example, if new children are added to the sample record, the additions are placed last. Thus: </p>
| |
| <p class="code">ADD CHILD = SARAH
| |
| ADD CHILD = PATRICK
| |
| </p>
| |
| <p>
| |
| results in the record:</p>
| |
| <p class="output">FATHER = JOHN DOE
| |
| CHILD = ELIZABETH
| |
| CHILD = ROBERT
| |
| CHILD = SARAH
| |
| CHILD = PATRICK
| |
| </p>
| |
|
| |
| ====The INSERT statement====
| |
| <p>
| |
| If the order of occurrence is important, the INSERT statement can be used to add new occurrences. See the discussion on [[#INSERT statement|INSERT statement]]. </p>
| |
|
| |
| ===CHANGE statement===
| |
| <p>
| |
| The CHANGE statement alters only the first occurrence of a field in a record. </p>
| |
|
| |
| ====Syntax====
| |
| <p>
| |
| You can use this form of the CHANGE statement if there is more than one occurrence: </p>
| |
| <p class="syntax">CHANGE <span class="term">fieldname</span> = <span class="term">value1</span> TO <span class="term">value2</span>
| |
| </p>
| |
| <p>
| |
| This form, like the <var>CHANGE fieldname</var> statement, can be used only inside a FOR EACH RECORD loop. It deletes the first occurrence of the pair fieldname = value1 from a record, and adds the pair fieldname = value2 to the record. The new value is added either in the position occupied by the original value or at the end of the record, depending upon the update attribute specified for the field by the file manager. See the discussion in [[#UPDATE field attribute|UPDATE field attribute]]. </p>
| |
| <p>
| |
| If the specified field, <var class="term">fieldname</var> = <var class="term">value1</var>, does not appear in the record, <var class="term">fieldname</var> = <var class="term">value2</var> is simply added to the record. If the specified <var class="term">fieldname</var> = <var class="term">value1</var> pair appears more than once in the record, only the first occurrence of it is deleted. The pair, <var class="term">fieldname</var> = <var class="term">value2</var>, is added just once. Occurrences of the field name that have other values are not altered by the statement. </p>
| |
|
| |
| ===DELETE statement===
| |
| <p>
| |
| The DELETE statement deletes only the first occurrence of the field in the record by default. </p>
| |
|
| |
| ====Two forms of DELETE statement====
| |
| <p>
| |
| For multiply occurring fields, two forms of the DELETE statement are provided; however only for use inside a FOR EACH RECORD loop: </p>
| |
| <table>
| |
| <tr class="head">
| |
| <th>To delete... </th>
| |
| <th>Syntax </th>
| |
| <th>Usage</th>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td>A particular occurrence </td>
| |
| <td nowrap>DELETE <i>fieldname</i> = <i>value</i> </td>
| |
| <td>
| |
| <p>
| |
| To delete the first occurrence of the pair, <var class="term">fieldname</var> = <var class="term">value</var>, from a record. Occurrences of the field that have other values are not removed. If the field with the specified value:</p>
| |
| <p>
| |
| Occurs more than once in the record, only the first occurrence is deleted. </p>
| |
| <p>
| |
| Cannot be found, no deletion occurs.</p>
| |
| </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td>Every occurrence of the field in the record </td>
| |
| <td>DELETE EACH <i>fieldname</i> </td>
| |
| <td>To delete all occurrences of the specified field name. The field to be deleted cannot have the INVISIBLE attribute. </td>
| |
| </tr>
| |
| </table>
| |
|
| |
| ====Use with the FOR EACH OCCURRENCE statement====
| |
| <p>
| |
| See [[#Deleting occurrences of fields and field groups|Deleting occurrences]] for a discussion of deleting occurrences using the FOR EACH OCCURRENCE OF (FEO) statement.</p>
| |
| | |
| ====Use with subscripts====
| |
| <p>
| |
| See [[#DELETE statement|DELETE statement]] for a discussion of using the DELETE statement with subscripts.</p>
| |
|
| |
| ==SORT RECORDS statement==
| |
| <p>
| |
| When a multiply occurring field is chosen as a sort key, each record in the set being sorted is processed once using the first occurrence of the field as the key. </p>
| |
|
| |
| ===EACH modifier with one sort field===
| |
| <p>
| |
| If the EACH modifier is present in the SORT statement and if there are n occurrences of the field in the record, similar records are created in the sorted copy of the original set. </p>
| |
|
| |
| ====Example====
| |
| <p>
| |
| The following request:</p>
| |
| <p class="code">SORT RECORDS IN FIND.RECS BY EACH KEY
| |
| </p>
| |
| <p>
| |
| generates three temporary records for the single permanent record in which the field named <code>KEY</code> occurs three times:</p>
| |
| <p class="code">KEY = COMPUTER
| |
| KEY = CORPORATION
| |
| KEY = AMERICA
| |
| </p>
| |
| <p>
| |
| The records generated are:</p>
| |
| <p class="output">1 KEY = COMPUTER 2 KEY = CORPORATION
| |
| KEY = CORPORATION KEY = AMERICA
| |
| KEY = AMERICA KEY = COMPUTER
| |
|
| |
| 3 KEY = AMERICA
| |
| KEY = COMPUTER
| |
| KEY = CORPORATION
| |
| </p>
| |
| <p>
| |
| These correspond to the <var class="term">n</var> cyclic permutations of the set of field occurrences and, in this example, are sorted into the order 3, 1, 2 (if no other option is selected). Statements that refer to the sorted set, such as PRINT, PRINT EACH, NOTE, and PRINT ALL INFORMATION (PAI), reflects the permutation. No record is generated if <var class="term">n</var> = 0.</p>
| |
| | |
| ===EACH modifier with several key fields===
| |
| <p>
| |
| When the EACH option is selected for several keys, <var class="term">n</var> occurrences of one key and <var class="term">m</var> of another produce differently permuted records. If either <var class="term">n</var> or <var class="term">m</var> equal 0, no records are generated. </p>
| |
|
| |
| ====Example====
| |
| <p>
| |
| This request:</p>
| |
| <p class="code">BEGIN
| |
| FIND.RECS: IN CLIENTS FIND ALL RECORDS FOR WHICH
| |
| INCIDENT = T1
| |
| END FIND
| |
| SORT.RECS: SORT RECORDS IN FIND.RECS BY FULLNAME -
| |
| AND EACH INCIDENT DATE
| |
| FOR EACH RECORD IN SORT.RECS
| |
| PRINT FULLNAME WITH INCIDENT DATE -
| |
| AT COLUMN 25
| |
| END FOR
| |
| END
| |
| </p>
| |
| <p>
| |
| produces printed output of:</p>
| |
| <p class="output">ABBOTT, FRANKLIN G 860323
| |
| ABBOTT, GAIL H 861022
| |
| ABRAMS, RUTH Z 861115
| |
| ABRAMS, RUSSELL Y 870218
| |
| ABBOTT, FRANKLIN G 870424
| |
| ABBOTT, GAIL H 871123
| |
| . .
| |
| . .
| |
| . .
| |
| </p>
| |
| | |
| ===If no occurrences are present===
| |
| <p>
| |
| A record that does not contain at least one occurrence of the INCIDENT DATE field produces no printed output. Similarly:</p>
| |
| <p class="code">SORT RECORDS IN FIND.RECS BY EACH A AND EACH B
| |
| </p>
| |
| <p>
| |
| would produce nothing for those records that do not have at least one occurrence of both A and B. </p>
| |
|
| |
| ==FOR EACH RECORD statement==
| |
| <p>
| |
| The FOR EACH RECORD IN ORDER BY statement retrieves and loops on only the first occurrence of a field in a record. </p>
| |
|
| |
| ===EACH modifier===
| |
| <p>
| |
| If there is more than one value of a field in a record, the special modifier, EACH, can be used to retrieve and loop on all values of the field. </p>
| |
| <p>
| |
| The EACH modifier only can be used on a FOR EACH RECORD statement that specifies index order processing (the IN ORDER BY fieldname clause must be used and the field must have the ORDERED attribute). The VALUE IN phrase must be used to retrieve the current value of the ORDERED field driving the loop. </p>
| |
|
| |
| ====Example====
| |
| <p>
| |
| This example of the FOR EACH RECORD IN ORDER BY statement:</p>
| |
| <p class="code">BEGIN
| |
| FR1: FOR EACH RECORD IN ORDER BY EACH INCIDENT DATE
| |
| PRINT VALUE IN FR1 WITH FULLNAME AT COLUMN 25
| |
| END FOR
| |
| END
| |
| </p>
| |
| <p>
| |
| returns each record in order by each value of the ORDERED field, as follows:</p>
| |
| <p class="output">760323 ABBOTT, FRANKLIN G
| |
| 761022 ABBOTT, GAIL H
| |
| 761115 ABRAMS, RUTH Z
| |
| 770218 ABRAMS, RUSSELL Y
| |
| .
| |
| .
| |
| .
| |
| </p>
| |
|
| |
| ==Special statements for multiply occurring fields and field groups==
| |
| <p>
| |
| SOUL provides several statements for handling multiply occurring fields and [[Field group design|field groups]]. Field groups are supported as of Model 204 version 7.5.</p>
| |
| <ul>
| |
| <li>COUNT OCCURRENCES (used with singly occurring fields, too)</li>
| |
| <li>FOR ALL OCCURRENCES OF FIELDGROUP </li>
| |
| <li>FOR EACH OCCURRENCE (used with singly occurring fields, too)</li>
| |
| <li>FOR FIELDGROUP</li>
| |
| <li>DELETE EACH OCCURRENCE</li>
| |
| </ul>
| |
| <p class="note"><b>Note:</b> See also the [[#INSERT statement|INSERT statement]], which you can use to add new occurrences of a field.</p>
| |
|
| |
| ===COUNT OCCURRENCES OF statement===
| |
| <p>
| |
| The COUNT OCCURRENCES OF (CTO) statement counts the number of occurrences of the named field in the current record. </p>
| |
|
| |
| ====Syntax====
| |
| <p>
| |
| The format of the COUNT OCCURRENCES statement is:</p>
| |
| <p class="syntax"><span class="term">label</span>: COUNT OCCURRENCES OF <span class="term">fieldname</span>
| |
| </p>
| |
| <p>
| |
| or</p>
| |
| <p class="syntax"><span class="term">label</span>: CTO <span class="term">fieldname</span>
| |
| </p>
| |
| <p>
| |
| The field name cannot be subscripted. The COUNT OCCURRENCES OF statement can appear only within a FOR EACH RECORD loop.</p>
| |
| <p>
| |
| The COUNT OCCURRENCES statement is supported in remote file and scattered group contexts.</p>
| |
|
| |
| ====COUNT IN clause====
| |
| <p>
| |
| The COUNT IN clause refers to the count obtained by the COUNT OCCURRENCES OF statement. This request:</p>
| |
| <p class="code">BEGIN
| |
| FIND.RECS: IN VEHICLES FIND ALL RECORDS
| |
| END FIND
| |
| FOR 5 RECORDS IN FIND.RECS
| |
| NO.OF.VINS: COUNT OCCURRENCES OF VIN
| |
| PRINT OWNER POLICY WITH ' INSURES ' WITH -
| |
| COUNT IN NO.OF.VINS WITH ' VEHICLE(S)'
| |
| END FOR
| |
| END
| |
| </p>
| |
| <p>
| |
| generates the following output:</p>
| |
| <p class="output">100025 INSURES 1 VEHICLE(S)
| |
| 100030 INSURES 1 VEHICLE(S)
| |
| 100032 INSURES 1 VEHICLE(S)
| |
| 100051 INSURES 1 VEHICLE(S)
| |
| 100058 INSURES 1 VEHICLE(S)
| |
| </p>
| |
|
| |
| ===FOR ALL OCCURRENCES OF FIELDGROUP (FAO FIELDGROUP) statement===
| |
| The FAO statement collects the field group IDs for all occurrences, then processes against that list. FAO is <em>not valid</em> for use against multiply-occurring fields, only against field groups (introduced in Model 204 V7.5).
| |
|
| |
| ====Syntax====
| |
| <p>
| |
| The format of the statement is:</p>
| |
| <p class="syntax">FOR ALL OCCURRENCES OF FIELDGROUP (<span class="term">fgname</span> | %%<span class="term">varGrp</span>)
| |
| </p>
| |
| Where:
| |
| <ul>
| |
| <li><var class="term">fgname</var> specifies a field group name.</li>
| |
| | |
| <li>%%<var class="term">varGrp</var> specifies a field group name variable.</li>
| |
| </ul>
| |
| The difference between an FAO statement and an FEO statement is that the FAO statement is less affected by insertions or deletions of FIELDGROUP <var class="term">fgname</var> within the loop, due to the semantics of field group IDs. This means that deleting the current occurrence within the loop will not affect occurrences referenced in subsequent iterations.
| |
| | |
| ===FOR EACH OCCURRENCE OF loops===
| |
| <p>
| |
| On each loop of FOR EACH OCCURRENCE OF (FEO), the VALUE IN and OCCURRENCE IN labels refer to value and position, respectively, of the next field occurrence, starting with occurrence 1 and increasing by 1 for each pass through the loop. When the next field occurrence number is greater than the number of field occurrences in the record, the loop terminates. </p>
| |
|
| |
| ====Syntax====
| |
| <p>
| |
| The format of the FOR EACH OCCURRENCE loop is:</p>
| |
| <p class="syntax"><span class="term">label</span>: FOR EACH OCCURRENCE OF <span class="term">fieldname</span>
| |
| </p>
| |
| <p>
| |
| Alternatively,</p>
| |
| <p class="syntax"><span class="term">label</span>: FEO <span class="term">fieldname</span>
| |
| </p>
| |
| <p>
| |
| The FOR EACH OCCURRENCE OF statement is supported in remote file and scattered group contexts.</p>
| |
| | |
| To work with specific field values inside an FEO loop, two styles of reference are supported: OCCURRENCE IN {label}, which is used as a field subscript, and VALUE IN {label} with is a direct reference to a field occurrence.
| |
|
| |
| ====Example====
| |
| <p>
| |
| Consider this record:</p>
| |
| <p class="code">FIRST NAME = RICHARD
| |
| LAST NAME = SMITH
| |
| CHILD = HENRY
| |
| CHILD = SALLY
| |
| CHILD = JANE
| |
| ADDRESS = AVON DRIVE
| |
| </p>
| |
| <p>
| |
| This request creates a separate record for each child.</p>
| |
| <p class="code">BEGIN
| |
| FD.REC: FIND ALL RECORDS FOR WHICH
| |
| FIRST NAME = RICHARD
| |
| LAST NAME = SMITH
| |
| END FIND
| |
| FOR EACH RECORD IN FD.REC
| |
| NOTE.ADD: NOTE ADDRESS
| |
| CHILD.LOOP: FOR EACH OCCURRENCE OF CHILD
| |
| PRINT VALUE IN CHILD.LOOP
| |
| STORE RECORD
| |
| FIRST NAME = VALUE IN CHILD.LOOP
| |
| LAST NAME = SMITH
| |
| ADDRESS = VALUE IN NOTE.ADD
| |
| END STORE
| |
| END FOR
| |
| END FOR
| |
| END
| |
| </p>
| |
|
| |
| ====Simulating a FOR EACH VALUE loop====
| |
| <p>
| |
| The FOR EACH OCCURRENCE OF statement can be used to simulate a FOR EACH VALUE loop if the field contains a static collection of known values. Consider the values of states. The user sets up a single record that has a multiply occurring field in sorted sequence as follows: </p>
| |
| <p class="code">TYPE = STATE
| |
| CODE = ALABAMA
| |
| CODE = ARKANSAS
| |
| .
| |
| .
| |
| CODE = WYOMING
| |
| </p>
| |
| <p>
| |
| These statements begin a request to generate a report in order by state:</p>
| |
| <p class="code">BEGIN
| |
| FIND.TYPE: FIND ALL RECORDS FOR WHICH
| |
| TYPE = STATE
| |
| END FIND
| |
| FOR EACH RECORD IN FIND.TYPE
| |
| EACH.CODE: FOR EACH OCCURRENCE OF CODE
| |
| FIND.STATE: FIND ALL RECORDS FOR WHICH
| |
| STATE = VALUE IN EACH.CODE
| |
| END FIND
| |
| FOR EACH RECORD IN FIND.STATE
| |
| .
| |
| .
| |
| </p>
| |
| <p>
| |
| This method has the advantage of eliminating the internal sort required by FOR EACH VALUE IN ORDER and provides an easy way to simulate a FOR EACH VALUE loop for a field that does not have the FRV or ORDERED attribute. However, a change in the list of values can require a recreation of the TYPE record to keep the values in order. Recreation is not required if the UPDATE IN PLACE field attribute has been specified for the CODE field and if the new and old values occupy the same place in order. Recreation also is not required if the [[#INSERT statement|INSERT statement]] is used correctly. </p>
| |
|
| |
| ====VALUE IN with FOR EACH OCCURRENCE loops====
| |
| <p>
| |
| VALUE IN references to FOR EACH OCCURRENCE (FEO) statements from outside the FEO loop does not compile. Such references receive the following error message:</p>
| |
| <p class="code">M204.0311 UNACCEPTABLE STATEMENT REFERENCE
| |
| </p>
| |
| <p>
| |
| At runtime, the space occupied in STBL by the FEO value is reclaimed after each iteration of the FEO loop (including the last). This results in a reduction in the runtime STBL space requirements of some programs that use FEO.</p>
| |
| <p>
| |
| To avoid getting that error, move the value into a %variable inside the FEO loop, and then reference the %variable outside the FEO loop.</p>
| |
| | |
| ====FOR EACH OCCURRENCE against INVISIBLE fields====
| |
| <p>
| |
| Using FOR EACH OCCURRENCE (FEO) syntax against INVISIBLE fields is a waste of processing time. An FEO causes a scan of the current Table B record, but INVISIBLE fields are not stored in Table B, so an FEO against an INVISIBLE field can never find any occurrences. Prior to V4R2.0 this programming flaw was masked because using FEO syntax against an INVISIBLE field compiled and evaluated successfully, although it never found occurrences. </p>
| |
| <p>
| |
| Beginning in V4R2.0, FEO syntax against an INVISIBLE field results in compilation error:</p>
| |
| <p class="code">M204.0320 Field is invisible. Field = <i>fieldname</i>
| |
| </p>
| |
| | |
| ===Deleting occurrences of fields and field groups===
| |
| <p>
| |
| The DELETE EACH statement can be used to delete all occurrences. </p>
| |
| | |
| <p class="note"><b>Note:</b> You must take care when deleting occurrences of a field or fieldgroup using the FOR EACH OCCURRENCE loop. When used to delete occurrences, and without a numbered occurrence reference on the field name, the first 50% of occurrences of a multiply occurring field are deleted. If there are an odd number of occurrences of the field on the record, the first half, up to and including the middle occurrence, are deleted.</p>
| |
|
| |
| ====Example====
| |
| Suppose the following statement is specified for the <code>RICHARD SMITH</code> record described previously:
| |
| <p class="code"> for each occurrence in fd.rec
| |
| del.child: for each occurrence of child
| |
| delete child
| |
| end for
| |
| end for
| |
| </p>
| |
| <p>
| |
| The record originally contained these <code>CHILD</code> entries:</p>
| |
| <p class="code">CHILD=HENRY
| |
| CHILD=SALLY
| |
| CHILD=JANE
| |
| </p>
| |
| <p>
| |
| On the first pass through the loop, the first value, <code>HENRY</code>, is selected and deleted. At the end of the first pass, the record contains these <code>CHILD</code> entries:</p>
| |
| <p class="code">CHILD=SALLY
| |
| CHILD=JANE
| |
| </p>
| |
| <p>
| |
| On the second pass through the loop, the <code>DELETE CHILD</code> statement again deletes the first occurrence of the field as described in [[#DELETE statement|DELETE statement]]. Since <code>HENRY</code> has already been deleted, <var class="product">Model 204</var> deletes the first entry, <code>SALLY</code>.</p>
| |
| <p>
| |
| After the second pass, the <var>FOR EACH OCCURRENCE</var> loop terminates. This is because the value in <code>DEL.CHILD</code> should be the next (third) occurrence, but after two passes, only one occurrence remains on the record. Therefore, at the end of the <var>FOR EACH OCCURRENCE</var> loop, the remaining value in the <code>CHILD</code> field is:</p>
| |
| <p class="code">CHILD=JANE
| |
| </p>
| |
| <p class="note"><b>Note:</b> In general, it is a mistake to reference a multiply occurring field in an <var>FEO</var> loop without using an occurrence subscript. An unsubscripted reference always refers to the first occurrence of a field.</p>
| |
| | |
| ====Example 2====
| |
| Now suppose an occurrence reference is added to the field in the <var>FEO</var> loop:
| |
| <p class="code"> for each record in fd.rec
| |
| del.child: for each occurrence of child
| |
| delete child(occurrence in del.child)
| |
| end for
| |
| end for
| |
| </p>
| |
| <p>
| |
| The above will result in <em>every other</em> occurrence being deleted, because the occurrence reference continues to increment upward while the list of occurrences is also shifted, so the second time through the loop, the occurrence pointer is pointing to the item that was formerly the third item, then the fifth item, then the seventh item. Again, this is generally not what the programmer intends.</p>
| |
| | |
| <p>The solution is either:
| |
| <ul>
| |
| <li>Use the <var>DELETE EACH</var> syntax.</li>
| |
| | |
| <li>Loop over the occurrences in reverse order. </li>
| |
| </ul>
| |
| | |
| There is no specific syntax for reversing the order of an <var>FEO</var> loop, so you must count the occurrences and step backward through them in an index loop, like this:</p>
| |
| <p class="code">for each record in %myRecordSet
| |
| childCount: -
| |
| count occurrences of child
| |
| for %x from count in childCount to 1 by -1
| |
| delete child(%x)
| |
| end for
| |
| end for
| |
| </p>
| |
| | |
| <p>Stepping backward through a set is also the standard practice in <var>StringList</var> and <var>NamedArrayList</var> objects, when deletions may occur. This technique is especially worth keeping in mind in situations where only some occurrences may be deleted.</p>
| |
| | |
| <p>When using field groups, the <var>FOR ALL OCCURRENCES</var> syntax, introduced with Model 204 V7.5, performs as expected.</p>
| |
| | |
| ====Deleting with an FEO FIELDGROUP versus FAO FIELDGROUP loop====
| |
| An <var>FEO FIELDGROUP</var> statement on field groups has the same semantics as an <var>FEO</var> statement on a single field. When you iterate in an <var>FEO FIELDGROUP</var> or <var>FEO</var> loop, the next occurrence processed is the occurrence number one greater than the one processed before, whether or not it is one you have already processed (because of insertions) or whether or not you skip one or more (because of deletions). For example:
| |
| <ul>
| |
| <li>Following the standard behavior for moving <em>forward</em> through a set of occurrences in an <var>FEO</var> loop, <var>FEO FIELDGROUP</var> deletes <i>every other</i> occurrence of the field group:
| |
| <p class="code">xon: -
| |
| feo fieldgroup vehicle
| |
| delete fieldgroup(occurrence in xon)
| |
| end for</p>
| |
| <p>
| |
| This behavior is a historical anomaly, but it is maintained for backward compatibility purposes. </p></li>
| |
| | |
| <li>To delete <i>all</i> occurrences of a field group, use an <var>FAO FIELDGROUP</var> statement:
| |
| <p class="code">fao fieldgroup vehicle
| |
| delete fieldgroup
| |
| end for
| |
| </p></li>
| |
| </ul>
| |
| | |
| ===FOR FIELDGROUP statement===
| |
| The FOR FIELDGROUP statement operates on a specific occurrence of a field group. The occurrence is indicated by either an occurrence number or a field group ID number.
| |
|
| |
| ====Syntax====
| |
| The format of the statement is:
| |
| <p class="syntax"><span class="literal">FOR FIELDGROUP (</span><span class="term">fgname</span> <span class="squareb">|</span> %%<span class="term">varFgname</span><span class="literal">)</span> <span class="squareb">{</span> <span class="literal">(</span><span class="term">occurrence-number</span><span class="literal">)</span> <span class="squareb">|</span> = <span class="term">fieldgroupID</span> <span class="squareb">}</span>
| |
| </p>
| |
| Where:
| |
| <ul>
| |
| <li><var class="term">fgname</var> specifies a field group name. </li>
| |
| | |
| <li>%%<var class="term">varGrp</var> specifies a field group name variable. </li>
| |
| | |
| <li><var class="term">occurrence-number</var> specifies an occurrence within that field group. The occurrence number must be enclosed in parentheses.
| |
| <p>
| |
| The <var>[[$FieldgroupOccurrence]]</var> function returns the field group occurrence value. </p></li>
| |
| | |
| <li><var class="term">fieldgroupID</var> specifies a field group ID, which is unique for a record. A field group ID is assigned when a field group is added to the record, is equal to one more than the highest field group ID that has been assigned in the record, and is not reused if its field group is deleted.
| |
| <p>
| |
| <var class="term">fieldgroupID</var> must be preceded by an equal sign. </p>
| |
| <p>
| |
| The <var>[[$FieldgroupId]]</var> function returns the field group ID. </p></li>
| |
| </ul>
| |
| | |
| ====Examples====
| |
| This <var>FOR FIELDGROUP</var> statement sets the third occurrence of the <code>DRIVER</code> field group as the context for the <var>Print</var> statement:
| |
| <p class="code">FR Where ...
| |
| For Fieldgroup DRIVER (3)
| |
| Print DRIVER_ID
| |
| End For
| |
| End For </p>
| |
| <p>
| |
| This <var>FOR FIELDGROUP</var> statement uses a [[Using variables and values in computation#Field name variables|field name variable]] to set the <code>DRIVER</code> field group that has ID <var class="term">%fgid</var> as the context for the <var>Print</var> statement: </p>
| |
| <p class="code">FR Where ...
| |
| %driver = 'DRIVER'
| |
| For Fieldgroup %%driver = %fgid
| |
| Print DRIVER_ID And DRIVER_NAME
| |
| End For
| |
| End For
| |
| </p>
| |
| | |
| ==Setting field group context==
| |
| To access data in a field group, first establish the record context using the
| |
| <var>FOR EACH RECORD</var> (<var>FR</var>) or <var>FOR RECORD NUMBER</var> (<var>FRN</var>) statement. Then to access the occurrences of the field group, you typically use an <var>FAO FIELDGROUP</var> or <var>FEO FIELDGROUP</var> loop.
| |
|
| |
| ===Using a FOR ALL OCCURRENCES OF loop===
| |
| You can set field group context with an <var>FAO</var> loop. For example:
| |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD
| |
| FAO: FAO FIELDGROUP VEHICLE
| |
| IF COLOR IS LIKE '*RED*' THEN
| |
| PRINT 'POLICY:' AT 5 AND POLICY_NUMBER AND -
| |
| 'COLOR=' WITH COLOR
| |
| %RED = %RED + 1
| |
| END IF
| |
| END FOR
| |
| END FOR
| |
| PRINT 'NUMBER OF RED CARS:' AND %RED
| |
| END
| |
| </p>
| |
| The result is:
| |
| <p class="output"> POLICY: 100001 COLOR=VICTORY RED
| |
| POLICY: 100007 COLOR=RED
| |
| POLICY: 100011 COLOR=VICTORY RED
| |
| ...
| |
| NUMBER OF RED CARS: 214
| |
|
| |
| ...and so on...
| |
| </p>
| |
|
| |
| ===Using a FOR EACH OCCURRENCE loop===
| |
| An <var>FEO</var> loop on a field group establishes a field group context. Inside the loop, references to field group fields are to their occurrences in their field group. For example:
| |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| FEO: FEO FIELDGROUP VEHICLE
| |
| %DRIVER_ID = OTHER_DRIVER
| |
| PRINT OCCURRENCE IN FEO AND MAKE AND MODEL AND -
| |
| 'OTHER DRIVER(S):' AT 30 AND EACH OTHER_DRIVER
| |
| PRINT 'FIRST:' AT 30 AND %DRIVER_ID AND -
| |
| 'THIRD:' AND OTHER_DRIVER(3)
| |
| END FOR
| |
| END FOR
| |
| END </p>
| |
| | |
| The result is:
| |
| <p class="output">1 AUDI A4 QUATTRO OTHER DRIVER(S): 100035 100037 100036
| |
| FIRST: 100035 THIRD: 100036
| |
| 2 CADILLAC SEVILLE OTHER DRIVER(S):
| |
| FIRST: THIRD:
| |
| </p>
| |
| <p>
| |
| An important difference between an <var>FAO FIELDGROUP</var> statement and an <var>FEO
| |
| FIELDGROUP</var> statement is that the <var>FAO FIELDGROUP</var> statement collects the
| |
| field group IDs for all occurrences, then processes against that list. Because of
| |
| this, it is less affected by insertions or deletions of occurrences of field groups
| |
| within the loop. Deleting the current occurrence within the
| |
| loop, for example, will not affect occurrences referenced in subsequent iterations.
| |
| For further discussion of this, see [[#FEO loops and field group context|FEO loops and field group context]], below. </p>
| |
| | |
| ===Using a FOR FIELDGROUP block===
| |
| You can use a field group occurrence established by a [[#FOR FIELDGROUP statement|FOR FIELDGROUP block]] as the context for references to its members.
| |
| | |
| For example, the following <var>PAFGI</var> (<var>PRINT ALL FIELD GROUP INFORMATION</var>) statement outputs the contents of only the third occurrence of field group <code>GRP</code>:
| |
| <p class="code">IN FILE WHATEVER FRN %RECNO
| |
| FOR FIELDGROUP GRP(3)
| |
| PRINT ’*** Third occurrence of field group GRP’
| |
| PAFGI
| |
| END FOR
| |
| END FOR </p>
| |
| | |
| ===Accessing field group members while not in field group context===
| |
| You can access field group occurrences by using the occurrence number
| |
| directly in the FR loop, if the field is [[Field design#AT-MOST-ONE, REPEATABLE, and EXACTLY-ONE attributes|EXACTLY-ONE or AT-MOST-ONE]]. So, instead of using this <var>FEO FIELDGROUP</var> loop to print the <code>MAKE</code> and <code>MODEL</code> for the three vehicles in the <code>VEHICLE</code> field group:
| |
| <p class="code">BEGIN
| |
| FR WHERE POLICY_NUMBER = 100095
| |
| FEO FIELDGROUP VEHICLE
| |
| PRINT MAKE AND MODEL
| |
| END FOR
| |
| END FOR
| |
| END
| |
| </p>
| |
| <p>
| |
| Output: </p>
| |
| <p class="output">VOLKSWAGEN NEW BEETLE
| |
| MITSUBISHI ECLIPSE
| |
| CHEVROLET SUBURBAN </p>
| |
| <p>
| |
| You can also access the <code>MAKE</code> and <code>MODEL</code> (<var>EXACTLY-ONE</var>) fields directly within the <var>FR</var> loop by using occurrence numbers: </p>
| |
| <p class="code">BEGIN
| |
| FR WHERE POLICY_NUMBER = 100095
| |
| PRINT MAKE AND MODEL
| |
| PRINT MAKE(2) AND MODEL(2)
| |
| PRINT MAKE(3) AND MODEL(3)
| |
| END FOR
| |
| END </p>
| |
| <p>
| |
| Output: </p>
| |
| <p class="output">VOLKSWAGEN NEW BEETLE
| |
| MITSUBISHI SUBURBAN
| |
| CHEVROLET SUBURBAN </p>
| |
| <p class="note"><b>Note:</b>
| |
| If <code>MAKE</code> and <code>MODEL</code> are <var>REPEATABLE</var> fields or defined to all field groups (<code>FIELDGROUP *</code>), attempting to access them with just an <var>FR</var> loop will fail. </p>
| |
|
| |
| ===Missing data in field groups===
| |
| As with non-field group field references for missing occurrences, the field values are returned as null (see the reference to <code>OTHER_DRIVER(3)</code> in the preceding example). The exception is <var>EXACTLY-ONE</var> fields in field groups, where the field's default value is returned for missing occurrences.
| |
| | |
| ===Handling nested field group context===
| |
| If field groups are nested, you can always retrieve an <var>EXACTLY-ONE</var> field in a field group inside the current context without establishing that nested field group's context.
| |
| <var>EXACTLY-ONE</var> fields in specific field groups (as opposed to fields defined with <code>FIELDGROUP *</code> that belong to all field groups) can be retrieved outside the field group context.
| |
| In the following example, <code>CLAIM-NUMBER</code> is an <var>EXACTLY-ONE</var> field in field group <code>CLAIM</code> which is nested within field group <code>VEHICLE</code>:
| |
|
| |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100095
| |
| PRINT POLICY_NUMBER
| |
| FEO FIELDGROUP VEHICLE
| |
| PRINT MAKE AT 5 AND MODEL
| |
| PRINT '1)' AND CLAIM_NUMBER
| |
| PRINT '2)' AND CLAIM_NUMBER(2)
| |
| PRINT '3)' AND CLAIM_NUMBER(3)
| |
| END FOR
| |
| END FOR
| |
| END </p>
| |
| <p>
| |
| The result is: </p>
| |
| <p class="output">100095
| |
| VOLKSWAGEN NEW BEETLE
| |
| 1)
| |
| 2)
| |
| 3)
| |
| MITSUBISHI ECLIPSE
| |
| 1) 100059
| |
| 2) 100064
| |
| 3)
| |
| CHEVROLET SUBURBAN
| |
| 1)
| |
| 2)
| |
| 3)
| |
| </p>
| |
| | |
| ===Updating fields in a field group===
| |
| <p>
| |
| <var>EXACTLY-ONE</var> fields cannot be <var>ADD</var>ed, <var>INSERT</var>ed or <var>DELETE</var>d. You can only <var>CHANGE</var> them.
| |
| </p>
| |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| FEO FIELDGROUP VEHICLE
| |
| ADD MAKE = 'XXX'
| |
| INSERT MAKE(1) = %NOTHING
| |
| DELETE MAKE
| |
| CHANGE COLOR(4) TO 'YYYY'
| |
| END FOR
| |
| END </p>
| |
| <p>
| |
| The result is: </p>
| |
| <p class="output"><nowiki>*** 1 M204.2853: ADD NOT ALLOWED FOR EXACTLY-ONE FIELD
| |
| == 'XXX'
| |
| *** 2 M204.0228: PART OF STATEMENT IGNORED
| |
| *** 3 M204.2853: INSERT NOT ALLOWED FOR EXACTLY-ONE
| |
| FIELD
| |
| == %NOTHING
| |
| *** 4 M204.0228: PART OF STATEMENT IGNORED
| |
| *** 5 M204.2853: DELETE NOT ALLOWED FOR EXACTLY-ONE
| |
| FIELD
| |
| *** M204.1042: COMPILATION ERRORS
| |
| </nowiki>
| |
| </p>
| |
| | |
| ===Handling invalid occurrence numbers===
| |
| The following <code>PRINT MAKE(3)</code> statement prints a null and without error, even if <code>MAKE</code> was defined as <var>EXACTLY-ONE</var>. This is consistent with Model 204 behavior for non-field group <var>EXACTLY-ONE</var> and <var>OCCURS</var> fields. That is, you can request occurrence 4 of an <var>EXACTLY-ONE</var> or <var>OCCURS 1</var> field in the record, and Model 204 returns a null. Model 204 ignores invalid occurrence numbers such as negative numbers or 0. 0 is treated the same as 1.
| |
| | |
| In the following example, <code>MAKE</code> and <code>MODEL</code> are <var>EXACTLY-ONE</var> fields:
| |
| | |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| PRINT '1' AND MAKE AND MODEL
| |
| PRINT '2' AND MAKE(2) AND MODEL(2)
| |
| PRINT '3' AND MAKE(3) AND MODEL(3)
| |
| END FOR
| |
| END </p>
| |
| The result is:
| |
| <p class="output">1 AUDI A4 QUATTRO
| |
| 2 CADILLAC SEVILLE
| |
| 3
| |
| </p>
| |
|
| |
| <p>
| |
| In addition to retrieving field values inside an <var>FEO FIELDGROUP</var> loop, fields in that field group can be updated, that is, added, inserted, changed, and deleted: </p>
| |
| <p class="code">BEGIN
| |
|
| |
| %GLASSES IS STRING LEN 50
| |
| %GLASSES = 'CORRECTIVE LENSES REQUIRED'
| |
|
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| FEO FIELDGROUP DRIVER
| |
| PRINT 'BEFORE ..'
| |
| PAFGI
| |
| ADD DRIVER_RESTRICTIONS = 'MEDICAL RESTRICTIONS PRESENT'
| |
| INSERT DRIVER_RESTRICTIONS(3) = %GLASSES
| |
| DELETE DRIVER_RESTRICTIONS(4)
| |
| CHANGE DRIVER_MARITAL_STATUS TO 'WIDOWED'
| |
| PRINT 'AFTER ...'
| |
| PAFGI
| |
| END FOR
| |
| END </p>
| |
|
| |
| The result is:
| |
| <p class="output">BEFORE ..
| |
| \DRIVER = 1
| |
| DRIVER_ID = 100034
| |
| DRIVER_NAME = CUMMINGS, BETTY S
| |
| DRIVER_MARITAL_STATUS = SINGLE
| |
| DRIVER_GENDER = F
| |
| DRIVER_DATE_OF_BIRTH = 19791225
| |
| /DRIVER = 1
| |
| AFTER ...
| |
| \DRIVER = 1
| |
| DRIVER_ID = 100034
| |
| DRIVER_NAME = CUMMINGS, BETTY S
| |
| DRIVER_MARITAL_STATUS = WIDOWED
| |
| DRIVER_GENDER = F
| |
| DRIVER_DATE_OF_BIRTH = 19791225
| |
| DRIVER_RESTRICTIONS = MEDICAL RESTRICTIONS PRESENT
| |
| DRIVER_RESTRICTIONS = CORRECTIVE LENSES REQUIRED
| |
| /DRIVER = 1
| |
| BEFORE ..
| |
| \DRIVER = 2
| |
| </p>
| |
| | |
| ==Constraint violations for field groups==
| |
| For <var>ADD</var>, <var>INSERT</var>, and <var>DELETE</var> statements, you can get an <var>EXACTLY-ONE</var> constraint violation, as well as other field constraint violations. In the previous example, had you attempted to add, insert, or delete the field <code>DRIVER_ID</code>, you would have received the following error message:
| |
| <p class="code">M204.2853: (ADD/DELETE/INSERT) NOT ALLOWED FOR EXACTLY-ONE FIELD
| |
| </p>
| |
| In general, the behavior of updating statements mimics the Model 204 handling of exception cases. For example, a <var>DELETE</var> of an occurrence that is not there is ignored. A <var>CHANGE</var> statement for an absent occurrence becomes an <var>ADD</var> statement.
| |
| | |
| ==Referencing fields in nested field groups==
| |
| You can reference a field from the containing context even inside a field group context. For example:
| |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| FEO FIELDGROUP DRIVER
| |
| PRINT POLICY_NUMBER AND DRIVER_NAME
| |
| END FOR
| |
| END
| |
|
| |
| 100013 CUMMINGS, BETTY S
| |
| 100013 CUMMINGS, EDDIE R
| |
| 100013 CUMMINGS, LEE V
| |
| 100013 CUMMINGS, MARY U
| |
| 100013 CUMMINGS, ROBERT T
| |
| </p>
| |
| | |
| See the discussion in the next section regarding the oddities of <var>DELETE</var> processing with <var>FEO</var> loops.
| |
|
| |
| ==FEO loops and field group context==
| |
| On each iteration of a field group <var>FEO</var> loop, the current field group is set as the field group context. If that field group is deleted and a field in that field group is referenced you get a request canceling error.
| |
|
| |
| <var>FEO</var> on field groups has the same semantics as those on a single field. When you iterate in an <var>FEO FIELDGROUP</var>, the next occurrence processed is the occurrence number one greater than the one processed before, whether or not it is one you have already processed (because of insertions) or whether or not you skip one or more (because of deletions).
| |
|
| |
| The problem with deleting repeating fields, or field groups, in order in an FEO loop is that the internal pointer is updated after each deletion, resulting in a default behavior of deleting every other occurrence of the repeating field or field group, which can also cause an error when the final deletion is attempted and the pointer is now set to a value larger than the final occurrence:
| |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| FEO FIELDGROUP DRIVER
| |
| PRINT POLICY_NUMBER AND DRIVER_NAME
| |
| END FOR
| |
| END
| |
|
| |
| 100013 CUMMINGS, BETTY S
| |
| 100013 CUMMINGS, EDDIE R
| |
| 100013 CUMMINGS, LEE V
| |
| 100013 CUMMINGS, MARY U
| |
| 100013 CUMMINGS, ROBERT T
| |
|
| |
| BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| PRINT POLICY_NUMBER
| |
| PRINT 'BEFORE...'
| |
| FEO FIELDGROUP DRIVER
| |
| PRINT DRIVER_NAME AT 5
| |
| END FOR
| |
| FEO FIELDGROUP DRIVER
| |
| DELETE FIELDGROUP
| |
| END FOR
| |
| PRINT 'AFTER....'
| |
| FEO FIELDGROUP DRIVER
| |
| PRINT DRIVER_NAME AT 5
| |
| END FOR
| |
| END
| |
|
| |
| 100013
| |
| BEFORE...
| |
| CUMMINGS, BETTY S
| |
| CUMMINGS, EDDIE R
| |
| CUMMINGS, LEE V
| |
| CUMMINGS, MARY U
| |
| CUMMINGS, ROBERT T
| |
| AFTER....
| |
| CUMMINGS, EDDIE R
| |
| CUMMINGS, MARY U
| |
| </p>
| |
| | |
| The intent of the above code is clearly to delete <em>every</em> occurrence of the field group, not every <em>other</em> occurrence, but this anomalous result is maintained as part of SOUL for backward compatibility reasons. The three approaches to deleting <em>all</em> occurrences are:
| |
| <ul>
| |
| <li>Use the <var>DELETE EACH</var> syntax.</li>
| |
| <li>Loop backward through the set of occurrences in an index loop.</li>
| |
| <li>Use <var>FOR ALL OCCURRENCES</var> (<var>FAO</var>), introduced in Model 204 version 7.5. </li>
| |
| </ul>
| |
| | |
| <p class="code">BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100013
| |
| PRINT POLICY_NUMBER
| |
| PRINT 'BEFORE...'
| |
| FAO FIELDGROUP DRIVER
| |
| PRINT DRIVER_NAME AT 5
| |
| END FOR
| |
| FAO FIELDGROUP DRIVER
| |
| DELETE FIELDGROUP
| |
| END FOR
| |
| PRINT 'AFTER....'
| |
| FAO FIELDGROUP DRIVER
| |
| PRINT DRIVER_NAME AT 5
| |
| END FOR
| |
| END
| |
|
| |
| 100013
| |
| BEFORE...
| |
| CUMMINGS, BETTY S
| |
| CUMMINGS, EDDIE R
| |
| CUMMINGS, LEE V
| |
| CUMMINGS, MARY U
| |
| CUMMINGS, ROBERT T
| |
| AFTER....
| |
|
| |
| BEGIN
| |
| IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100095
| |
| PRINT '...BEFORE...'
| |
| FAO FIELDGROUP VEHICLE
| |
| PRINT MAKE AND MODEL
| |
| END FOR
| |
| PRINT 'ADD A HONDA PILOT ...'
| |
| ADD FIELDGROUP VEHICLE
| |
| MAKE = HONDA
| |
| MODEL = PILOT
| |
| * ... OTHER VEHICLE FIELDS
| |
| END ADD
| |
| PRINT '...AFTER....'
| |
| FAO FIELDGROUP VEHICLE
| |
| PRINT MAKE AND MODEL
| |
| END FOR
| |
| END
| |
|
| |
| ...BEFORE...
| |
| VOLKSWAGEN NEW BEETLE
| |
| MITSUBISHI ECLIPSE
| |
| CHEVROLET SUBURBAN
| |
|
| |
| ADD A HONDA PILOT ...
| |
| ...AFTER....
| |
| VOLKSWAGEN NEW BEETLE
| |
| MITSUBISHI ECLIPSE
| |
| CHEVROLET SUBURBAN
| |
| HONDA PILOT
| |
| </p>
| |
|
| |
| ==UPDATE field attribute==
| |
|
| |
| ===Impact of changing a value===
| |
| <p>
| |
| When the user changes the value of a field, how <var class="product">Model 204</var> changes the occurrence depends upon whether the field was defined with the <var>UPDATE IN PLACE</var> or <var>UPDATE AT END</var> attribute, as follows:</p>
| |
| <table>
| |
| <tr class="head">
| |
| <th>Attribute </th>
| |
| <th>How the update works...</th>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>UPDATE IN PLACE</var> (the default) </td>
| |
| <td>The value of the field occurrence is changed but its position in the record is preserved. To change the order of values, the user must delete the old value and add the new one in separate statements. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>UPDATE AT END</var> </td>
| |
| <td>The existing occurrence is deleted and the new one is automatically added at the end. <var>UPDATE AT END</var> is normally specified for applications that depend on value rotation to accomplish aging. </td>
| |
| </tr>
| |
| </table>
| |
|
| |
| ====Example====
| |
| <p>
| |
| This example includes both approaches to updating. Suppose a record has the following fields:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = HENRY
| |
| CHILD = SALLY
| |
| CHILD = JANE
| |
| </p>
| |
| <p>
| |
| You could use the technique illustrated below to add a last name to each child. (This technique involves the use of %variables, which are discussed in [[Using variables and values in computation]].)</p>
| |
| <p class="code">BEGIN
| |
| FIND.RECS: FIND ALL RECORDS FOR WHICH
| |
| NAME = RICHARD SMITH
| |
| END FIND
| |
| FOR EACH RECORD IN FIND.RECS
| |
| EACH.CHILD FOR EACH OCCURRENCE OF CHILD
| |
| %A = VALUE IN EACH.CHILD WITH ' SMITH'
| |
| CHANGE CHILD = VALUE IN EACH.CHILD TO %A
| |
| END FOR
| |
| END FOR
| |
| END
| |
| </p>
| |
|
| |
| ===If the UPDATE IN PLACE option is specified===
| |
| <p>
| |
| If the <var>UPDATE IN PLACE</var> option has been specified for the <code>CHILD</code> field, then the <var>FOR EACH OCCURRENCE</var> loop change each occurrence of <code>CHILD</code> in turn. </p>
| |
| <p>
| |
| On the first pass through the loop, the first value, <code>HENRY</code>, is selected and changed to <code>HENRY SMITH</code>. After the first pass, the record looks like this:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = HENRY SMITH
| |
| CHILD = SALLY
| |
| CHILD = JANE
| |
| </p>
| |
| <p>
| |
| At the end of the second pass, SALLY is changed:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = HENRY SMITH
| |
| CHILD = SALLY SMITH
| |
| CHILD = JANE
| |
| </p>
| |
| <p>
| |
| At the end of the third pass, JANE is changed:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = HENRY SMITH
| |
| CHILD = SALLY SMITH
| |
| CHILD = JANE SMITH
| |
| </p>
| |
|
| |
| ===If the UPDATE AT END option is specified===
| |
| <p>
| |
| If the <var>UPDATE AT END</var> option has been specified for the <code>CHILD</code> field, the <var>FOR EACH OCCURRENCE</var> loop proceeds as described here.</p>
| |
| <p>
| |
| On the first pass through the <var>FOR EACH OCCURRENCE</var> loop the first value, <code>HENRY</code>, is selected and changed to <code>HENRY SMITH</code>. The act of changing, however, causes the value <code>HENRY</code> to be deleted and the value <code>HENRY SMITH</code> to be added as the last child. Thus after the first pass, the record looks like this:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = SALLY
| |
| CHILD = JANE
| |
| CHILD = HENRY SMITH
| |
| </p>
| |
| <p>
| |
| On the second pass through the loop, <code>JANE</code>, which is now the second occurrence of <code>CHILD</code>, is deleted and <code>JANE SMITH</code> is added to the end of the record:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = SALLY
| |
| CHILD = HENRY SMITH
| |
| CHILD = JANE SMITH
| |
| </p>
| |
| <p>
| |
| On the third pass, the third occurrence is <code>JANE SMITH</code>, and the record ends with:</p>
| |
| <p class="code">NAME = RICHARD SMITH
| |
| CHILD = SALLY
| |
| CHILD = HENRY SMITH
| |
| CHILD = JANE SMITH
| |
| </p>
| |
|
| |
| ==Subscripts==
| |
| <p>
| |
| Subscripts can be included in <var class="product">Model 204</var> field references to facilitate the selection of particular occurrences of multiply occurring fields. Any field name can be followed by a parenthesized expression. The value of this expression is used as an ordinal number which specifies the desired occurrence of the named field. For example: </p>
| |
| <p class="code">INCIDENT(3)
| |
| COURSE.NUMBER(2)
| |
| TRANSACTION(A+B)
| |
| </p>
| |
|
| |
| ====Example====
| |
| <p>
| |
| This request illustrates a class schedule where subscripts are used to change the room number for a course:</p>
| |
| <p class="code">BEGIN
| |
| COURSE: FIND ALL RECORDS FOR WHICH
| |
| REC = ROOM ASSIGNMENT
| |
| END FIND
| |
| CHANGE: FOR EACH RECORD IN COURSE
| |
| IF ROOM(1) EQ '214A' THEN
| |
| CHANGE ROOM(1) TO '566A'
| |
| END IF
| |
| IF ROOM(2) EQ '214A' THEN
| |
| CHANGE ROOM(2) TO '566A'
| |
| END IF
| |
| END FOR
| |
| END
| |
| </p>
| |
|
| |
| ===Subscripted field extraction===
| |
| <p>
| |
| Subscripted field references attempt to maintain their position inside a record much as an FEO loop attempts to maintain its position inside a record. This means that subscripted field references tend to be as efficient as FEO loops. </p>
| |
| <p>
| |
| The following is an example of using subscripted field extraction for a field that is a member of a field group. An <var>FEO</var> loop populates two arrays with the corresponding values of group members <code>INCIDENT</code> and <code>INCIDENT_DATE</code>:</p>
| |
| <p class="code">%inc is string array (12) no fs
| |
| %idate is string array (12) no fs
| |
| FeoIdata:
| |
| feo INCIDENT
| |
| %inc(occurence in FeoIdata) = value in FeoIdata
| |
| %idate(occurence in FeoIdata) = INCIDENT_DATE(occurence in FeoIdata)
| |
| end for
| |
| </p>
| |
| <p>
| |
| If you use multiple <var>FEO</var> loops for field group processing, it is possible that using this technique will require additional VTBL resources for procedures with an extremely large number of sorts or subscripted field references.</p>
| |
|
| |
| ===Evaluation of subscript expressions===
| |
| <p>
| |
| The evaluation of subscript expressions is subject to the rules for determining an integer result for an arithmetic expression as described in [[Using variables and values in computation#Arithmetic operations|Arithmetic operations]]. </p>
| |
|
| |
| ===Statements and phrases with which you cannot use subscripts===
| |
| <p>
| |
| Subscripted field references can appear anywhere that unsubscripted references can, except in the following statements and phrases:</p>
| |
| <table>
| |
| <tr class="head">
| |
| <th>Statements you cannot use with subscripts </th>
| |
| <th>
| |
| Because...</th>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>ADD</var> </td>
| |
| <td>Adds a new occurrence of a field. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>BY EACH phrase</var> in the <var>SORT RECORDS</var> </td>
| |
| <td>Loops through all occurrences of a field. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>DELETE EACH statement</var> </td>
| |
| <td>Loops through all occurrences of a field. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>EACH phrase</var> in a <var>PRINT</var> specification</td>
| |
| <td>Loops through all occurrences of a field. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>FILE</var> </td>
| |
| <td>Deals with fields having the INVISIBLE attribute, which cannot be the object of subscripted references. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>FIND</var></td>
| |
| <td>Locates records without regard to which occurrence of a field contains the desired value. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>FOR EACH OCCURRENCE</var></td>
| |
| <td>Loops through all occurrences of a field. Field references within FOR EACH OCCURRENCE loops can be subscripted, depending upon the individual statements in which the references appear. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>FOR EACH VALUE</var> </td>
| |
| <td>Loops through all values of all occurrences of the specified field. Field references within FOR EACH VALUE loops are not allowed at all, unless the field reference is embedded in a nested FOR EACH RECORD loop. See [[Value loops#Setting up a value loop on one field and printing a value of another|Setting up a value loop on one field and printing a value of another]] for more information.</td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>IN ORDER BY EACH phrase</var> in the <var>FOR EACH RECORD </var></td>
| |
| <td>Loops through all occurrences of a field. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>PRINT n </var></td>
| |
| <td>Loops through all occurrences of a field. </td>
| |
| </tr>
| |
| | |
| <tr>
| |
| <td><var>STORE RECORD</var></td>
| |
| <td>Adds fields in the order of appearance in the statement. </td>
| |
| </tr>
| |
| </table>
| |
|
| |
| ===Unsubscripted field references===
| |
| <p>
| |
| An unsubscripted field reference in a context in which subscripted references are allowed is always equivalent to a subscripted reference with a value of one.</p>
| |
|
| |
| ===Do not use subscripts with INVISIBLE fields===
| |
| <p>
| |
| You cannot make subscripted references to fields that have the <var>INVISIBLE</var> attribute (see the discussion on field attributes in [[Field attributes]]). These fields are not truly multiply occurring, although they can have several different values in a single record. A subscript specified for a field with the <var>INVISIBLE</var> attribute is ignored. </p>
| |
|
| |
| ==Subscript validity rules==
| |
| <p>
| |
| The rules presented below indicate whether or not a subscript value is valid and what action to take if the value is not valid. These rules take into account: </p>
| |
| <ul>
| |
| <li>The value of the subscript</li>
| |
| <li>The context in which the subscript appears</li>
| |
| <li>The description of the subscripted field </li>
| |
| </ul>
| |
|
| |
| ===Explanation of the rules===
| |
| <p>
| |
| In these rules, two quantities are used:</p>
| |
| <ol>
| |
| <li>N is the maximum number of occurrences that can be stored in a record for a given field. For a preallocated field, N equals the value of <var class="term">n</var> in the <var>OCCURS</var> clause of the field's description. For other fields, N has no limit. </li>
| |
|
| |
| <li>P is the number of nonempty occurrences of the referenced field found in the specified record when the reference is evaluated. </li>
| |
| </ol>
| |
| <p>
| |
| For a summary of rules for preallocated fields, refer to the discussion on preallocated fields in [[Data maintenance#Storing values in preallocated fields|Storing values in preallocated fields]]. </p>
| |
|
| |
| ===INSERT statement===
| |
| <p>
| |
| The <var>INSERT</var> statement, like the <var>ADD</var> statement, is used for adding new occurrences of a field. <var>INSERT</var> is used to add occurrences when the order of the values is important and the values are added out of order. </p>
| |
| <p>
| |
| The <var>INSERT</var> statement is supported in remote file and scattered group contexts. The <var>INSERT</var> statement is not supported for Large Object fields.</p>
| |
|
| |
| ====Syntax====
| |
| <p>
| |
| The format of the <var>INSERT</var> statement is:</p>
| |
| <p class="syntax">INSERT <span class="term">fieldname</span> [(<span class="term">subscript</span>)] = <span class="term">value</span>
| |
| </p>
| |
|
| |
| ====Example====
| |
| <p>
| |
| Assume a record with these fields:</p>
| |
| <p class="code">DEPT = PERSONNEL
| |
| DEPT = FINANCE
| |
| DEPT = MARKETING
| |
| </p>
| |
| <p>
| |
| The following statement:</p>
| |
| <p class="code">INSERT DEPT(3) = ACCOUNTING
| |
| </p>
| |
| <p>
| |
| results in this record:</p>
| |
| <p class="output">DEPT = PERSONNEL
| |
| DEPT = FINANCE
| |
| DEPT = ACCOUNTING
| |
| DEPT = MARKETING
| |
| </p>
| |
|
| |
| ====Subscript validity rules====
| |
| <p>
| |
| [[#INSERT statement|INSERT statement]] lists validity rules for subscripts. In this table:</p>
| |
| <ul>
| |
| <li>P is the number of occurrences of the field in the record when the <var>INSERT</var> statement is issued. </li>
| |
|
| |
| <li>S is the subscript specified in the <var>INSERT</var> statement.
| |
| <table>
| |
| <caption>Subscript validation rules</caption>
| |
| <tr class="head">
| |
| <th>If P and S values are: </th>
| |
| <th>
| |
| Then <var class="product">Model 204</var> takes this action:</th>
| |
| </tr>
| |
|
| |
| <tr>
| |
| <td>P > S</td>
| |
| <td>Inserts the new occurrence in front of the former Sth occurrence; the new occurrence becomes the current Sth occurrence of the field.</td>
| |
| </tr>
| |
|
| |
| <tr>
| |
| <td>P < S</td>
| |
| <td>Inserts the new occurrence of the field after the Pth occurrence; the new occurrence becomes the (P+1) occurrence.</td>
| |
| </tr>
| |
|
| |
| <tr>
| |
| <td>P = 0</td>
| |
| <td>Adds the new value at the end of the record, as in the <var>ADD</var> statement.</td>
| |
| </tr>
| |
|
| |
| <tr>
| |
| <td>S = 0, or no subscript</td>
| |
| <td>Treats the new value as if S = 1 and inserts the new value as the first occurrence, in front of any former occurrence of the field.</td>
| |
| </tr>
| |
|
| |
| <tr>
| |
| <td>S < 0</td>
| |
| <td>Does not add a new occurrence.</td>
| |
| </tr>
| |
| </table>
| |
| </li>
| |
| </ul>
| |
| <p>
| |
| For fields with the <var>INVISIBLE</var> attribute, only the index is affected. </p>
| |
|
| |
| ===PRINT statement===
| |
| <p>
| |
| In retrieval statements such as <var>PRINT</var>, subscript values less than zero or greater than P are invalid. Invalid references of this kind cause the null value to be returned. A subscript of zero returns the value of the first occurrence. </p>
| |
|
| |
| ===DELETE statement===
| |
| <p>
| |
| In the <var>DELETE</var> statement, subscript values less than one or greater than P are invalid. If an invalid reference of this kind is made, no action is taken. </p>
| |
| <p>
| |
| If several occurrences of a field are being deleted, you should be careful not to use DELETE in the following way: </p>
| |
| <p class="code">FOR EACH RECORD IN FIND.RECS
| |
| DELETE CLIENT(1)
| |
| DELETE CLIENT(2)
| |
| DELETE CLIENT(3)
| |
| END FOR
| |
| </p>
| |
| <p>
| |
| As the statements are executed, <var class="product">Model 204</var> deletes the first occurrence, <code>CLIENT(1)</code>, then locates the current second occurrence, which is the original <code>CLIENT(3)</code>, and deletes it. Then, because a third occurrence cannot be found, the operation stops, and the original <code>CLIENT(2)</code> is never deleted.</p>
| |
| <p>
| |
| In such a situation, deleting the occurrences in the reverse order achieves the desired result:</p>
| |
| <p class="code">FOR EACH RECORD IN FIND.RECS
| |
| DELETE CLIENT(3)
| |
| DELETE CLIENT(2)
| |
| DELETE CLIENT(1)
| |
| END FOR
| |
| </p>
| |
| <p>
| |
| The desired result also can be achieved by completely omitting the subscripts, as follows:</p>
| |
| <p class="code">FOR EACH RECORD IN FIND.RECS
| |
| DELETE CLIENT
| |
| DELETE CLIENT
| |
| DELETE CLIENT
| |
| END FOR
| |
| </p>
| |
|
| |
| ===CHANGE statement===
| |
| <p>
| |
| In the <var>CHANGE</var> statement, subscript values less than one or greater than P are treated as attempts to add a new occurrence (P+1). If (P+1) does not exceed N (the maximum number of occurrences that can be stored), the new occurrence is added to the record. If (P+1) does exceed N, the request is cancelled. </p>
| |
|
| |
| ===SORT RECORDS statement===
| |
| <p>
| |
| The use of subscripts in references to the recordset yielded by a
| |
| <var>SORT RECORDS</var> statement sometimes can produce unexpected results.
| |
| If the <var>BY EACH</var> option appears in a <var>SORT</var> statement, records in which the <var>BY EACH</var> field is multiply occurring are copied several times (once for each field occurrence) to the system scratch file CCATEMP.
| |
| In each copy, the occurrences of the <var>BY EACH</var> field are rotated, so that the occurrence used as the sort key appears first. Therefore, a subscripted reference to this field can yield different values for different copies of the record. </p>
| |
|
| |
| </div> <!-- end of toc limit div -->
| |
| | |
| [[Category:SOUL]]
| |