Data maintenance: Difference between revisions

From m204wiki
Jump to navigation Jump to search
(Automatically generated page update)
m (more conversion cleanup)
Line 1: Line 1:
===Overview===
==Overview==
<p><var class="product">Model&nbsp;204</var> data are maintained and updated with a variety of statements. This chapter describes data maintenance statements and special conditions regarding their usage. </p>
<p>
====Data maintenance statements====
<var class="product">Model&nbsp;204</var> data are maintained and updated with a variety of statements. This topic describes data maintenance statements and special conditions regarding their usage. </p>
<p>Use the following statements to perform basic data maintenance (record and field additions and updates):</p>
===Data maintenance statements===
<p>
Use the following statements to perform basic data maintenance (record and field additions and updates):</p>
<table>
<table>
<tr class="head">
<tr class="head">
Line 8: Line 11:
<th> Action</th>
<th> Action</th>
</tr>
</tr>
<tr>
<tr>
<td><var>ADD</var> </td>
<td><var>ADD</var> </td>
<td>Place a new field-value pair on a record.</td>
<td>Place a new field-value pair on a record.</td>
</tr>
</tr>
<tr>
<tr>
<td><var>CHANGE</var> </td>
<td><var>CHANGE</var> </td>
<td>Alter the value of fields in a record.</td>
<td>Alter the value of fields in a record.</td>
</tr>
</tr>
<tr>
<tr>
<td><var>DELETE</var> </td>
<td><var>DELETE</var> </td>
<td>Remove fields from a record.</td>
<td>Remove fields from a record.</td>
</tr>
</tr>
<tr>
<tr>
<td><var>DELETE RECORD</var> </td>
<td><var>DELETE RECORD</var> </td>
<td>Remove a record from a <var class="product">Model&nbsp;204</var> file; this statement reclaims space occupied by the deleted record.</td>
<td>Remove a record from a <var class="product">Model&nbsp;204</var> file; this statement reclaims space occupied by the deleted record.</td>
</tr>
</tr>
<tr>
<tr>
<td><var>DELETE RECORDS</var> </td>
<td><var>DELETE RECORDS</var> </td>
<td>Remove sets of records from a <var class="product">Model&nbsp;204</var> file; this statement executes faster than the DELETE RECORD statement but does not reclaim the space occupied by the deleted records.</td>
<td>Remove sets of records from a <var class="product">Model&nbsp;204</var> file; this statement executes faster than the DELETE RECORD statement but does not reclaim the space occupied by the deleted records.</td>
</tr>
</tr>
<tr>
<tr>
<td><var>FILE RECORDS UNDER</var> </td>
<td><var>FILE RECORDS UNDER</var> </td>
<td>Save retrieved or collected sets of record numbers for reference in later requests. </td>
<td>Save retrieved or collected sets of record numbers for reference in later requests. </td>
</tr>
</tr>
<tr>
<tr>
<td><var>STORE RECORD</var> </td>
<td><var>STORE RECORD</var> </td>
<td>Put a new record to a <var class="product">Model&nbsp;204</var> file.</td>
<td>Put a new record to a <var class="product">Model&nbsp;204</var> file.</td>
</tr>
</tr>
<tr>
<tr>
<td><var>UPDATE RECORD </var></td>
<td><var>UPDATE RECORD </var></td>
Line 41: Line 52:
</tr>
</tr>
</table>
</table>
====Using FOR EACH RECORD loops====
<p>The User Language data maintenance statements handle one record at a time, therefore the data maintenance statements are always part of a FOR EACH RECORD loop. The data maintenance may involve a field-value pair for the field.</p>
===Using FOR EACH RECORD loops===
====Data used in examples in this chapter====
<p>
<p>Each statement is discussed separately on the pages that follow. To illustrate their usage, assume that the following two records have been stored:</p>
The User Language data maintenance statements handle one record at a time, therefore the data maintenance statements are always part of a FOR EACH RECORD loop. The data maintenance may involve a field-value pair for the field.</p>
===Data used in examples in this topic===
<p>
Each statement is discussed separately on the pages that follow. To illustrate their usage, assume that the following two records have been stored:</p>
<p class="code">VIN = A99999998E          VIN = X99999999Z
<p class="code">VIN = A99999998E          VIN = X99999999Z
MAKE = FORD                MAKE = FORD
MAKE = FORD                MAKE = FORD
Line 51: Line 66:
MODEL = FOCUS              MODEL = MUSTANG
MODEL = FOCUS              MODEL = MUSTANG
</p>
</p>
 
===ADD statement===
==ADD statement==
<b>Purpose</b>
<p>Add a new occurrence of a field and/or value to a record.</p>
====Purpose====
<b>Syntax</b>
<p>
<p>The basic format of the ADD statement is:</p>
Add a new occurrence of a field and/or value to a record.</p>
<p class="syntax">ADD <span class="term">fieldname</span> = {<span class="term">value</span> | (<span class="term">expression</span>)}
====Syntax====
<p>
The basic format of the ADD statement is:</p>
<p class="syntax">ADD <span class="term">fieldname</span> = {<span class="term">value</span> <span class="squareb">|</span> (<span class="term">expression</span>)}
</p>
</p>
<p>Where:</p>
<p>
<p><span class="term">fieldname</span> identifies the field in a record.</p>
Where:</p>
<p><span class="term">value</span> specifies the value you want to store.</p>
<p>
<p>(<span class="term">expression</span>) can be used in place of value to specify the resolved value at the time of evaluation. (<span class="term">expression</span>) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
<span class="term">fieldname</span> identifies the field in a record.</p>
<b>Example</b>
<p>
<p>Referring to the two sample stored records (see [[#Data used in examples in this chapter|Data used in examples in this chapter]]), this request:</p>
<span class="term">value</span> specifies the value you want to store.</p>
<p>
(<span class="term">expression</span>) can be used in place of value to specify the resolved value at the time of evaluation. (<span class="term">expression</span>) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
====Example====
<p>
Referring to the two sample stored records (see [[#Data used in examples in this topic|Data used in examples in this topic]]), this request:</p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS: FIND ALL RECORDS FOR WHICH
FIND.RECS: FIND ALL RECORDS FOR WHICH
Line 73: Line 98:
               ADD BODY = 2DR
               ADD BODY = 2DR
           END FOR
           END FOR
END  
END
</p>
</p>
<p>would change the records to:</p>
<p>
would change the records to:</p>
<p class="code">VIN = A99999998E        VIN = X99999999Z
<p class="code">VIN = A99999998E        VIN = X99999999Z
MAKE = FORD              MAKE = FORD
MAKE = FORD              MAKE = FORD
Line 81: Line 107:
BODY = 2DR              BODY = 2DR
BODY = 2DR              BODY = 2DR
YEAR = 98                YEAR = 04
YEAR = 98                YEAR = 04
MODEL = FOCUS            MODEL = MUSTANG  
MODEL = FOCUS            MODEL = MUSTANG
</p>
</p>
<p>You can also add Large Object data to <var class="product">Model&nbsp;204</var>, as shown using the following syntax:</p>
<p>
<b>Large Object field syntax</b>
You can also add Large Object data to <var class="product">Model&nbsp;204</var>, as shown using the following syntax:</p>
====Large Object field syntax====
<p class="syntax">ADD <span class="term">lob-name</span>=BUFFER,<span class="term">position</span>,<span class="term">length</span> [RESERVE <span class="term">n</span> [BYTES]]
<p class="syntax">ADD <span class="term">lob-name</span>=BUFFER,<span class="term">position</span>,<span class="term">length</span> [RESERVE <span class="term">n</span> [BYTES]]
</p>
</p>
<p>Where:</p>
<p>
Where:</p>
<ul>
<ul>
<li><span class="term">lob-name</span> specifies the field name of the Large Object data.</li>
<li><span class="term">lob-name</span> specifies the field name of the Large Object data.</li>
Line 103: Line 132:
</li>
</li>
</ul>
</ul>
<b>Example</b>
====Example====
<p class="code">BEGIN
<p class="code">BEGIN
IMAGE XYZ
IMAGE XYZ
Line 109: Line 139:
END IMAGE
END IMAGE
IDENTIFY IMAGE XYZ
IDENTIFY IMAGE XYZ
 
<b></b>* add LOB field with "CURRECn" to the records:
<b></b>* add LOB field with "CURRECn" to the records:
FOR EACH RECORD
FOR EACH RECORD
Line 119: Line 149:
   ADD MY.LOB.FIELD=BUFFER,1,10  RESERVE 200 BYTES
   ADD MY.LOB.FIELD=BUFFER,1,10  RESERVE 200 BYTES
END FOR
END FOR
 
<b></b>* print LOB data:
<b></b>* print LOB data:
FOR EACH RECORD
FOR EACH RECORD
Line 130: Line 160:
END
END
</p>
</p>
<p>This code would result in adding a large object field to each record containing the text "CURREC" followed by the internal record number and this output:</p>
<p>
This code would result in adding a large object field to each record containing the text "CURREC" followed by the internal record number and this output:</p>
<p class="code">A99999998E CURREC0
<p class="code">A99999998E CURREC0
X99999999Z CURREC1
X99999999Z CURREC1
</p>
</p>
<b>Usage</b>
<p>The ADD statement places an additional occurrence of a field-value pair on the record.</p>
====Usage====
<p>You can use the ADD statement to add any field to a record except for a sort or hash key field. You can use this statement only within a FOR EACH RECORD loop.</p>
<p>
<p>The ADD statement is supported in remote file and scattered group contexts.</p>
The ADD statement places an additional occurrence of a field-value pair on the record.</p>
<p>To use the ADD statement with multiply occurring fields, see [[Operations on multiply occurring fields#ADD statement|ADD statement]].          </p>
<p>
<p>For Large Object data, a compiler error is issued for ADD (and STORE) statements if the context to the right of the equal sign (=) is not a BUFFER reference.</p>
You can use the ADD statement to add any field to a record except for a sort or hash key field. You can use this statement only within a FOR EACH RECORD loop.</p>
<p>
The ADD statement is supported in remote file and scattered group contexts.</p>
<p>
To use the ADD statement with multiply occurring fields, see [[Operations on multiply occurring fields#ADD statement|ADD statement]].          </p>
<p>
For Large Object data, a compiler error is issued for ADD (and STORE) statements if the context to the right of the equal sign (=) is not a BUFFER reference.</p>
<p class="code">M204.0037: INVALID SYNTAX
<p class="code">M204.0037: INVALID SYNTAX
</p>
</p>
 
===CHANGE statement===
==CHANGE statement==
<b>Purpose</b>
<p>Alter a record by adding a field and value pair, or altering the value of an existing field within a record. </p>
====Purpose====
<b>Syntax</b>
<p>
<p>The basic format of the CHANGE statement is: </p>
Alter a record by adding a field and value pair, or altering the value of an existing field within a record. </p>
====Syntax====
<p>
The basic format of the CHANGE statement is: </p>
<p class="syntax">CHANGE <span class="term">fieldname</span> [<b></b>= <span class="term">value</span> |(<span class="term">expression</span>)] TO (<span class="term">newvalue</span> |(<span class="term">expression</span>))
<p class="syntax">CHANGE <span class="term">fieldname</span> [<b></b>= <span class="term">value</span> |(<span class="term">expression</span>)] TO (<span class="term">newvalue</span> |(<span class="term">expression</span>))
</p>
</p>
<p>Where:</p>
<p>
Where:</p>
<ul>
<ul>
<li><span class="term">fieldname</span> specifies the name of the field to add to the record, or identify the field where the value is changed.</li>
<li><span class="term">fieldname</span> specifies the name of the field to add to the record, or identify the field where the value is changed.</li>
Line 161: Line 203:
</li>
</li>
</ul>
</ul>
<b>Large Object field syntax</b>
<p>You can also change large object fields with the CHANGE statement using the following syntax:</p>
====Large Object field syntax====
<p>
You can also change large object fields with the CHANGE statement using the following syntax:</p>
<p class="syntax">CHANGE  <span class="term">lob-fieldname,position1,length</span> TO <span class="term">BUFFER position2,length</span>
<p class="syntax">CHANGE  <span class="term">lob-fieldname,position1,length</span> TO <span class="term">BUFFER position2,length</span>
</p>
</p>
Line 172: Line 216:
<li><span class="term">length</span> is a positive number specifying the length to move. The length can be a %variable or a constant.
<li><span class="term">length</span> is a positive number specifying the length to move. The length can be a %variable or a constant.
The source and target lengths must be equal.</li>
The source and target lengths must be equal.</li>
<p>If <span class="term">position</span> plus <span class="term">length</span> minus one exceeds the current length of the LOB field, the intervening bytes are filled with binary 0. If the file has FILEORG X'100' on, then any final length of the LOB field is allowed. Otherwise extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.</p>
<p>
<p>For example, if the buffer contains "ABCDEFGHIJKL" and the field is initially stored with:</p>
If <span class="term">position</span> plus <span class="term">length</span> minus one exceeds the current length of the LOB field, the intervening bytes are filled with binary 0. If the file has FILEORG X'100' on, then any final length of the LOB field is allowed. Otherwise extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.</p>
<p>
For example, if the buffer contains "ABCDEFGHIJKL" and the field is initially stored with:</p>
<p class="code">ADD LOB.FLD=BUFFER,1,3 RESERVE 500 BYTES
<p class="code">ADD LOB.FLD=BUFFER,1,3 RESERVE 500 BYTES
</p>
</p>
<p>The field would contain "ABC". If it was subsequently changed as follows:</p>
<p>
<p class="code">CHANGE LOB.FLD,5,10 TO BUFFER,1,10
The field would contain "ABC". If it was subsequently changed as follows:</p>
<p class="code">CHANGE LOB.FLD,5,10 TO BUFFER,1,10
</p>
</p>
<p>The field would then contain "ABC ABCDEFGHIJ" with position 4 being a binary zero. </p>
<p>
The field would then contain "ABC ABCDEFGHIJ" with position 4 being a binary zero. </p>
</li>
</li>
<li>TO BUFFER specifies the Universal Buffer. You can use BUFFER only in conjunction with a Large Object field.</li>
<li>TO BUFFER specifies the Universal Buffer. You can use BUFFER only in conjunction with a Large Object field.</li>
</li>
</li>
</ul>
</ul>
<b>Example</b>
<p>Referring to the two sample stored records (see [[#Data used in examples in this chapter|Data used in examples in this chapter]]), these statements:</p>
====Example====
<p>
Referring to the two sample stored records (see [[#Data used in examples in this topic|Data used in examples in this topic]]), these statements:</p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS: FIND ALL RECORDS FOR WHICH
FIND.RECS: FIND ALL RECORDS FOR WHICH
Line 193: Line 243:
               CHANGE COLOR TO BLUE
               CHANGE COLOR TO BLUE
           END FOR
           END FOR
END  
END
</p>
</p>
<p>cause <var class="product">Model&nbsp;204</var> to change the value of the COLOR field in each record to BLUE. The two records then appear as:</p>
<p>
cause <var class="product">Model&nbsp;204</var> to change the value of the COLOR field in each record to BLUE. The two records then appear as:</p>
<p class="code">VIN = A99999998E          VIN = X99999999Z
<p class="code">VIN = A99999998E          VIN = X99999999Z
MAKE = FORD              MAKE = FORD
MAKE = FORD              MAKE = FORD
Line 201: Line 252:
BODY = 2DR                BODY = 2DR
BODY = 2DR                BODY = 2DR
YEAR = 98                YEAR = 04
YEAR = 98                YEAR = 04
MODEL = FOCUS            MODEL = MUSTANG  
MODEL = FOCUS            MODEL = MUSTANG
</p>
</p>
<b>Example for Large Object</b>
====Example for Large Object====
<p class="code">BEGIN
<p class="code">BEGIN
IMAGE XYZ
IMAGE XYZ
Line 209: Line 261:
END IMAGE
END IMAGE
IDENTIFY IMAGE XYZ
IDENTIFY IMAGE XYZ
 
IN JUNK FOR EACH RECORD
IN JUNK FOR EACH RECORD
   * place LOB data into the buffer:
   * place LOB data into the buffer:
Line 216: Line 268:
   WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200
   WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200
   * change the LOB field to the contents of the buffer:
   * change the LOB field to the contents of the buffer:
   CHANGE MY.LOB.FIELD,1,50 TO BUFFER,1,50  
   CHANGE MY.LOB.FIELD,1,50 TO BUFFER,1,50
END FOR  
END FOR
 
<b></b>* print LOB data:
<b></b>* print LOB data:
FOR EACH RECORD  
FOR EACH RECORD
   * place LOB data into the buffer:  
   * place LOB data into the buffer:
   BUFFER,1,200=MY.LOB.FIELD,1,200  
   BUFFER,1,200=MY.LOB.FIELD,1,200
   * place contents of the buffer into image:  
   * place contents of the buffer into image:
   READ IMAGE XYZ FROM BUFFER
   READ IMAGE XYZ FROM BUFFER
   * print LOB data that has been placed into the buffer:  
   * print LOB data that has been placed into the buffer:
   PRINT VIN AND %XYZ:BUFF_DATA  
   PRINT VIN AND %XYZ:BUFF_DATA
END
END
</p>
</p>
<p>This code results in changing the large object field in each record to the text "This is the data for VIN" followed by the VIN field and this output. </p>
<p>
<p class="code">A99999998E This is the data for VIN A99999998E  
This code results in changing the large object field in each record to the text "This is the data for VIN" followed by the VIN field and this output. </p>
X99999999Z This is the data for VIN X99999999Z  
<p class="code">A99999998E This is the data for VIN A99999998E
X99999999Z This is the data for VIN X99999999Z
</p>
</p>
<b>Usage</b>
<p>You can use the CHANGE statement to change any field in a record except for a sort or hash key field. </p>
====Usage====
<p>You can use this statement only within a FOR EACH RECORD loop.                </p>
<p>
<p>The CHANGE statement is supported in remote file and scattered group contexts.</p>
You can use the CHANGE statement to change any field in a record except for a sort or hash key field. </p>
<p>If a CHANGE statement is applied to a record that does not contain the field to be changed, the specified field name and value are added to the record. </p>
<p>
<p>To use the CHANGE statement with multiply occurring fields, see [[Operations on multiply occurring fields#CHANGE statement|CHANGE statement]]. </p>
You can use this statement only within a FOR EACH RECORD loop.                </p>
<b>Changing Large Object fields and data</b>
<p>
<p>If you issue a CHANGE statement on a Large Object field to a record that does not contain the field, nothing happens. Unlike a non-Large Object field, a new occurrence of the field is not added to the record.</p>
The CHANGE statement is supported in remote file and scattered group contexts.</p>
<p>Extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.</p>
<p>
If a CHANGE statement is applied to a record that does not contain the field to be changed, the specified field name and value are added to the record. </p>
<p>
To use the CHANGE statement with multiply occurring fields, see [[Operations on multiply occurring fields#CHANGE statement|CHANGE statement]]. </p>
====Changing Large Object fields and data====
<p>
If you issue a CHANGE statement on a Large Object field to a record that does not contain the field, nothing happens. Unlike a non-Large Object field, a new occurrence of the field is not added to the record.</p>
<p>
Extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.</p>
<p class="note"><b>Note:</b> You cannot change the number of RESERVE bytes. Furthermore, facilities are not available to delete a portion of data or to insert data: for example, to replace 10 bytes with 25 bytes within Large Object data. When an attempt to insert or delete data is made the following error message is issued:</p>
<p class="note"><b>Note:</b> You cannot change the number of RESERVE bytes. Furthermore, facilities are not available to delete a portion of data or to insert data: for example, to replace 10 bytes with 25 bytes within Large Object data. When an attempt to insert or delete data is made the following error message is issued:</p>
<p class="code">M204.2693: SOURCE AND TARGET LENGTH MUST BE EQUAL
<p class="code">M204.2693: SOURCE AND TARGET LENGTH MUST BE EQUAL
</p>
</p>
<p>All Large Object data implicitly has the contiguous characteristic. A User Language procedure can store some amount of initial data and then extend the data up to the RESERVE number of bytes with subsequent CHANGE statements. For example:</p>
<p>
All Large Object data implicitly has the contiguous characteristic. A User Language procedure can store some amount of initial data and then extend the data up to the RESERVE number of bytes with subsequent CHANGE statements. For example:</p>
<p class="code">FR
<p class="code">FR
   * add initial 10 bytes:
   * add initial 10 bytes:
   ADD LOB.FLD=BUFFER,1,10 RESERVE 200 BYTES
   ADD LOB.FLD=BUFFER,1,10 RESERVE 200 BYTES
   * add increments of 10 bytes at  
   * add increments of 10 bytes at
   * positions 11, 21, 31, 41
   * positions 11, 21, 31, 41
   * moving data from the buffer to the field
   * moving data from the buffer to the field
Line 260: Line 323:
END
END
</p>
</p>
 
===DELETE statement===
==DELETE statement==
<b>Purpose</b>
<p>Remove fields from a record. </p>
====Purpose====
<b>Syntax</b>
<p>
<p>The format of the DELETE statement is:</p>
Remove fields from a record. </p>
<p class="code">DELETE fieldname [<b></b>= value |(expression)]  
====Syntax====
<p>
The format of the DELETE statement is:</p>
<p class="syntax">DELETE <span class="term">fieldname</span> [<b></b>= <span class="term">value</span> |(<span class="term">expression</span>)]
</p>
</p>
<p>Where:</p>
<p>
<p>fieldname specifies the name of the field to remove from the record.</p>
Where:</p>
<p>value option is required only if the field has the INVISIBLE attribute. (See the discussion in [[Field attributes]].)  </p>
<p>
<p>(expression) can be used in place of value to specify the resolved value at the time of evaluation. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
fieldname specifies the name of the field to remove from the record.</p>
<b>Example</b>
<p>
<p>For example, the request on the next page directs <var class="product">Model&nbsp;204</var> to remove the field BODY from the records retrieved by the FIND.RECS statement.</p>
value option is required only if the field has the INVISIBLE attribute. (See the discussion in [[Field attributes]].)  </p>
<p>
(expression) can be used in place of value to specify the resolved value at the time of evaluation. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
====Example====
<p>
For example, the request on the next page directs <var class="product">Model&nbsp;204</var> to remove the field BODY from the records retrieved by the FIND.RECS statement.</p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS: FIND ALL RECORDS FOR WHICH
FIND.RECS: FIND ALL RECORDS FOR WHICH
Line 281: Line 354:
               DELETE BODY
               DELETE BODY
           END FOR
           END FOR
END  
END
</p>
</p>
<p>The records then appear as:</p>
<p>
The records then appear as:</p>
<p class="code">VIN = A99999998E          VIN = X99999999Z
<p class="code">VIN = A99999998E          VIN = X99999999Z
MAKE = FORD              MAKE = FORD
MAKE = FORD              MAKE = FORD
Line 290: Line 364:
MODEL = FOCUS            MODEL = MUSTANG
MODEL = FOCUS            MODEL = MUSTANG
</p>
</p>
<b>Usage</b>
<p>You can use the DELETE fieldname statement on any field in a record except for a sort or hash key field. This statement can be used only within a FOR EACH RECORD loop.                          </p>
====Usage====
<p>If the DELETE fieldname statement is applied to a record that does not contain the field to be deleted, no action is taken on that record.        </p>
<p>
<p>The DELETE fieldname statement is supported in remote file and scattered group contexts.</p>
You can use the DELETE fieldname statement on any field in a record except for a sort or hash key field. This statement can be used only within a FOR EACH RECORD loop.                          </p>
<p>The DELETE fieldname statement supports Large Object data. Processing this statement frees the Table B and Table E data.</p>
<p>
<p>To use with multiply occurring fields, see [[Operations on multiply occurring fields#DELETE statement|DELETE statement]]. </p>
If the DELETE fieldname statement is applied to a record that does not contain the field to be deleted, no action is taken on that record.        </p>
 
<p>
===DELETE RECORD statement===
The DELETE fieldname statement is supported in remote file and scattered group contexts.</p>
<b>Purpose</b>
<p>
<p>Remove a record or sets of records from a <var class="product">Model&nbsp;204</var> file. </p>
The DELETE fieldname statement supports Large Object data. Processing this statement frees the Table B and Table E data.</p>
<b>Syntax</b>
<p>
<p>The format of the DELETE RECORD statement is:</p>
To use with multiply occurring fields, see [[Operations on multiply occurring fields#DELETE statement|DELETE statement]]. </p>
<p class="code">DELETE RECORD  
==DELETE RECORD statement==
====Purpose====
<p>
Remove a record or sets of records from a <var class="product">Model&nbsp;204</var> file. </p>
====Syntax====
<p>
The format of the DELETE RECORD statement is:</p>
<p class="syntax">DELETE RECORD
</p>
</p>
<b>Example</b>
<p>This request deletes all records found by the FIND statement.  </p>
====Example====
<p>
This request deletes all records found by the FIND statement.  </p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS: FIND ALL RECORDS FOR WHICH
FIND.RECS: FIND ALL RECORDS FOR WHICH
Line 314: Line 400:
               DELETE RECORD
               DELETE RECORD
           END FOR
           END FOR
END  
END
</p>
</p>
<b>Usage</b>
<p>When you delete records with the DELETE RECORD statement, the space those records occupy may be reclaimed depending on the file order. For more information on reclaiming space, refer to [[#Reused space|Reused space]]. </p>
====Usage====
<p>You can use this statement only inside a FOR EACH RECORD loop.</p>
<p>
<p>The DELETE RECORD statement is supported in remote file and scattered group contexts. </p>
When you delete records with the DELETE RECORD statement, the space those records occupy may be reclaimed depending on the file order. For more information on reclaiming space, refer to [[#Reused space|Reused space]]. </p>
<b>Limitation of the date/time stamp feature deleting records</b>
<p>
<p>The date/time stamp feature does not include support for DELETE RECORD or DELETE RECORDS processing. DELETE RECORD or DELETE RECORDS processing must be handled by your application software.</p>
You can use this statement only inside a FOR EACH RECORD loop.</p>
<p>As well, you can use logical delete techniques. However, in all forms of deleting records, it is your responsibility to maintain a log of record deletions, if you want one.</p>
<p>
===DELETE ALL RECORDS statement===
The DELETE RECORD statement is supported in remote file and scattered group contexts. </p>
<b>Purpose</b>
<p>Delete sets of records from a <var class="product">Model&nbsp;204</var> file. </p>
====Limitation of the date/time stamp feature deleting records====
<b>Syntax</b>
<p>
<p>The forms of this statement are:</p>
The date/time stamp feature does not include support for DELETE RECORD or DELETE RECORDS processing. DELETE RECORD or DELETE RECORDS processing must be handled by your application software.</p>
<p>
As well, you can use logical delete techniques. However, in all forms of deleting records, it is your responsibility to maintain a log of record deletions, if you want one.</p>
==DELETE ALL RECORDS statement==
====Purpose====
<p>
Delete sets of records from a <var class="product">Model&nbsp;204</var> file. </p>
====Syntax====
<p>
The forms of this statement are:</p>
<p class="code">DELETE [ALL] RECORDS IN label
<p class="code">DELETE [ALL] RECORDS IN label
 
DELETE [ALL] RECORDS ON [LIST] listname  
DELETE [ALL] RECORDS ON [LIST] listname
</p>
</p>
<ul>
<ul>
Line 338: Line 436:
</li>
</li>
</ul>
</ul>
<b>Example</b>
<p>This request deletes the set of records located by the FIND statement.</p>
====Example====
<p>
This request deletes the set of records located by the FIND statement.</p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS: FIND ALL RECORDS FOR WHICH
FIND.RECS: FIND ALL RECORDS FOR WHICH
Line 346: Line 446:
           END FIND
           END FIND
           DELETE ALL RECORDS IN FIND.RECS
           DELETE ALL RECORDS IN FIND.RECS
END  
END
</p>
</p>
<b>Usage</b>
<p>The DELETE ALL RECORDS statement initiates fewer internal operations and therefore executes faster than the DELETE RECORD statement. However, use the DELETE RECORD statement rather than DELETE ALL RECORDS for records with ORDERED or UNIQUE fields, to ensure that values in the Ordered Index accurately reflect the contents of the data stored in Table B.</p>
====Usage====
<p>In addition, when records are deleted with the DELETE ALL RECORDS IN statement, the space they occupy is not reclaimed. When it is desirable to reclaim space to expand existing records or to insert new records, use the DELETE RECORD statement.  </p>
<p>
<p>The DELETE ALL RECORDS statement is supported in remote file and scattered group contexts.</p>
The DELETE ALL RECORDS statement initiates fewer internal operations and therefore executes faster than the DELETE RECORD statement. However, use the DELETE RECORD statement rather than DELETE ALL RECORDS for records with ORDERED or UNIQUE fields, to ensure that values in the Ordered Index accurately reflect the contents of the data stored in Table B.</p>
===FILE RECORDS statement===
<p>
<b>Purpose</b>
In addition, when records are deleted with the DELETE ALL RECORDS IN statement, the space they occupy is not reclaimed. When it is desirable to reclaim space to expand existing records or to insert new records, use the DELETE RECORD statement.  </p>
<p>To file a set of records that were retrieved by a FIND statement or that were collected on a list. You can reference the set of records in later requests.        </p>
<p>
<b>Syntax</b>
The DELETE ALL RECORDS statement is supported in remote file and scattered group contexts.</p>
<p>The forms of this statement are:</p>
==FILE RECORDS statement==
====Purpose====
<p>
To file a set of records that were retrieved by a FIND statement or that were collected on a list. You can reference the set of records in later requests.        </p>
====Syntax====
<p>
The forms of this statement are:</p>
<p class="code">FILE RECORDS IN label UNDER fieldname = value
<p class="code">FILE RECORDS IN label UNDER fieldname = value
 
FILE RECORDS IN label UNDER fieldname = (expression)
FILE RECORDS IN label UNDER fieldname = (expression)
 
FILE RECORDS ON [LIST] listname  
FILE RECORDS ON [LIST] listname
               UNDER fieldname = value  
               UNDER fieldname = value
</p>
</p>
<b>Usage</b>
<p>The FILE RECORDS statement adds the pair:</p>
====Usage====
<p class="code">fieldname = value  
<p>
The FILE RECORDS statement adds the pair:</p>
<p class="code">fieldname = value
</p>
</p>
<p>or</p>
<p>
or</p>
<p class="code">fieldname = (expression)
<p class="code">fieldname = (expression)
</p>
</p>
<p>to the specified records. </p>
<p>The FILE RECORDS statement is supported in remote file and scattered group contexts.</p>
<p>The field used in a FILE RECORDS statement must have the INVISIBLE KEY or INVISIBLE ORDERED field attributes. Refer to [[Field attributes]] for more information.      </p>
<p>
<p>
In addition, the fieldname = value pair should be unique in the file. If the pair has appeared previously in other records, either by explicit field creation or by a previous FILE RECORDS statement, inconsistencies in the file can occur. The FILE RECORDS statement creates new index entries for the  
to the specified records. </p>
<p>
The FILE RECORDS statement is supported in remote file and scattered group contexts.</p>
<p>
The field used in a FILE RECORDS statement must have the INVISIBLE KEY or INVISIBLE ORDERED field attributes. Refer to [[Field attributes]] for more information.      </p>
<p>
In addition, the fieldname = value pair should be unique in the file. If the pair has appeared previously in other records, either by explicit field creation or by a previous FILE RECORDS statement, inconsistencies in the file can occur. The FILE RECORDS statement creates new index entries for the
fieldname = value pair, eliminating existing references.</p>
fieldname = value pair, eliminating existing references.</p>
<p class="note"><b>Note:</b> The index update generated by a FILE RECORDS UNDER statement is never deferred.</p>
<p class="note"><b>Note:</b> The index update generated by a FILE RECORDS UNDER statement is never deferred.</p>
<p>expression is enclosed in parentheses and is one of following expression types: function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression.</p>
<p>
<b>Example of using an expression</b>
expression is enclosed in parentheses and is one of following expression types: function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression.</p>
====Example of using an expression====
<p class="code">B
<p class="code">B
%REC IS STRING LEN 3
%REC IS STRING LEN 3
Line 417: Line 535:
END
END
</p>
</p>
<b>Locating filed record sets</b>
<p>FIND statements in later requests can locate the filed set of records by using the fieldname = value pair as the retrieval condition. For example, if a set of records were filed with the statement:</p>
====Locating filed record sets====
<p class="code">SAVE.RECS: FILE RECORDS IN FIND.RECS UNDER SAVE = 1  
<p>
FIND statements in later requests can locate the filed set of records by using the fieldname = value pair as the retrieval condition. For example, if a set of records were filed with the statement:</p>
<p class="code">SAVE.RECS: FILE RECORDS IN FIND.RECS UNDER SAVE = 1
</p>
</p>
<p>then:</p>
<p>
<p class="code">GET.RECS: FIND ALL RECORDS FOR WHICH SAVE = 1  
then:</p>
<p class="code">GET.RECS: FIND ALL RECORDS FOR WHICH SAVE = 1
</p>
</p>
<p>appearing either in the same request or in a later one would locate the records again.  </p>
<p>
<b>Using lists for filed record sets</b>
appearing either in the same request or in a later one would locate the records again.  </p>
<p>Two sets of records retrieved by different FIND statements can be filed together under the same fieldname = value pair only if both sets are first placed on a list, and then the list is filed by one statement, as in the following:    </p>
====Using lists for filed record sets====
<p>
Two sets of records retrieved by different FIND statements can be filed together under the same fieldname = value pair only if both sets are first placed on a list, and then the list is filed by one statement, as in the following:    </p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS:  FIND ALL RECORDS FOR WHICH
FIND.RECS:  FIND ALL RECORDS FOR WHICH
Line 439: Line 563:
             PLACE RECORDS IN FIND.T3S ON LIST COMPLIST
             PLACE RECORDS IN FIND.T3S ON LIST COMPLIST
SAVE.LIST:  FILE RECORDS ON LIST COMPLIST UNDER SAVE = T3S
SAVE.LIST:  FILE RECORDS ON LIST COMPLIST UNDER SAVE = T3S
END  
END
</p>
</p>
<p>If the SAVE.DOYLE statement were replaced with:</p>
<p>
<p class="code">SAVE.DOYLE: FILE RECORDS IN FIND.RECS UNDER SAVE = T3S  
If the SAVE.DOYLE statement were replaced with:</p>
<p class="code">SAVE.DOYLE: FILE RECORDS IN FIND.RECS UNDER SAVE = T3S
</p>
</p>
<p>the original references to SAVE = T3S would be lost as soon as the SAVE.LIST was executed. Thus, a second use of the same fieldname = value pair replaces the previous one.</p>
<p>
<b>Simulating the FILE RECORDS UNDER statement</b>
the original references to SAVE = T3S would be lost as soon as the SAVE.LIST was executed. Thus, a second use of the same fieldname = value pair replaces the previous one.</p>
<p>You can simulate the FILE RECORDS statement by explicitly adding a fieldname = value pair to a set of records. For example, if the SAVE.LIST statement in the previous example is replaced by:</p>
====Simulating the FILE RECORDS UNDER statement====
<p>
You can simulate the FILE RECORDS statement by explicitly adding a fieldname = value pair to a set of records. For example, if the SAVE.LIST statement in the previous example is replaced by:</p>
<p class="code">SAVE.LIST: FOR EACH RECORD ON LIST COMPLIST
<p class="code">SAVE.LIST: FOR EACH RECORD ON LIST COMPLIST
               ADD SAVE = T3S
               ADD SAVE = T3S
           END FOR  
           END FOR
</p>
</p>
<p>the index references to existing records that contain that fieldname = value pair are not invalidated. You are responsible for deleting such references, if deletion is desired.  </p>
<p>
===STORE RECORD statement===
the index references to existing records that contain that fieldname = value pair are not invalidated. You are responsible for deleting such references, if deletion is desired.  </p>
<b>Purpose</b>
<p>Use the STORE RECORD statement to add new records to a <var class="product">Model&nbsp;204</var> file. The <var class="term">fieldname</var>=<var class="term">value</var> pairs that constitute the new record must follow the STORE RECORD statement, one to a line, and must not be labeled. </p>
==STORE RECORD statement==
<b>Syntax</b>
<p>The format of the STORE RECORD statement is: </p>
====Purpose====
<p>
Use the STORE RECORD statement to add new records to a <var class="product">Model&nbsp;204</var> file. The <var class="term">fieldname</var>=<var class="term">value</var> pairs that constitute the new record must follow the STORE RECORD statement, one to a line, and must not be labeled. </p>
====Syntax====
<p>
The format of the STORE RECORD statement is: </p>
<p class="syntax">STORE RECORD
<p class="syntax">STORE RECORD
   <span class="term">fieldname</span> =[<span class="term">value1</span> | (<span class="term">expression1</span>)]
   <span class="term">fieldname</span> =[<span class="term">value1</span> <span class="squareb">|</span> (<span class="term">expression1</span>)]
   [<span class="term">fieldname2</span>=[<span class="term">value2</span> | (<span class="term">expression2</span>)]]
   [<span class="term">fieldname2</span>=[<span class="term">value2</span> <span class="squareb">|</span> (<span class="term">expression2</span>)]]
       .
       .
       .
       .
Line 469: Line 603:
       .
       .
       .]
       .]
END STORE [label]  
END STORE [label]
</p>
</p>
<p>Where:</p>
<p>
<p>(expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
Where:</p>
<p>You can also store Large Object fields to <var class="product">Model&nbsp;204</var>.</p>
<p>
<p class="syntax">STORE RECORD  
(expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
<p>
You can also store Large Object fields to <var class="product">Model&nbsp;204</var>.</p>
<p class="syntax">STORE RECORD
   <span class="term">lob-name</span>=BUFFER,<span class="term">position</span>,<span class="term">length</span> [RESERVE <span class="term">n</span> [BYTES]]
   <span class="term">lob-name</span>=BUFFER,<span class="term">position</span>,<span class="term">length</span> [RESERVE <span class="term">n</span> [BYTES]]
   .
   .
Line 481: Line 618:
END_STORE [<span class="term">label</span>]
END_STORE [<span class="term">label</span>]
</p>
</p>
<p>Where:</p>
<p>
Where:</p>
<ul>
<ul>
<li><var class="term">lob-name</var> specifies the field name of the Large Object field.</li>
<li><var class="term">lob-name</var> specifies the field name of the Large Object field.</li>
Line 497: Line 635:
</li>
</li>
</ul>
</ul>
<b>Examples</b>
====Examples====
<p class="code">BEGIN
<p class="code">BEGIN
STORE RECORD
STORE RECORD
Line 504: Line 643:
   POSITION = CHEMIST
   POSITION = CHEMIST
END STORE
END STORE
END  
END
</p>
</p>
<b>Using the THEN CONTINUE statement</b>
====Using the THEN CONTINUE statement====
<p class="code">%COLOR = 'BLUE'
<p class="code">%COLOR = 'BLUE'
STORE RECORD
STORE RECORD
Line 518: Line 658:
END STORE
END STORE
</p>
</p>
<b>Storing Large Object data</b>
====Storing Large Object data====
<p class="code">STORE RECORD
<p class="code">STORE RECORD
   NOVEL=BUFFER,%POSITION,%LENGTH
   NOVEL=BUFFER,%POSITION,%LENGTH
Line 525: Line 666:
END STORE
END STORE
</p>
</p>
<b>Using an expression</b>
====Using an expression====
<p class="code">B
<p class="code">B
%REC IS STRING LEN 3
%REC IS STRING LEN 3
Line 552: Line 694:
END
END
</p>
</p>
<b>Usage</b>
<p>Use an END STORE statement or another label to end the STORE RECORD statement. Do not end a STORE RECORD statement with an END BLOCK statement.          </p>
====Usage====
<p>This form of the STORE RECORD statement is used to add new records to any file that does not have the sorted or hashed option.</p>
<p>
<p>The STORE RECORD statement is supported in remote file and scattered group contexts.</p>
Use an END STORE statement or another label to end the STORE RECORD statement. Do not end a STORE RECORD statement with an END BLOCK statement.          </p>
<p>The THEN CONTINUE statement allows for the conditional building of a <var class="product">Model&nbsp;204</var> record. You can use any intervening statements after THEN CONTINUE and before END STORE.</p>
<p>
<p>The statements following the THEN CONTINUE statement of the STORE RECORD block operate as if they were coded within a FRN $CURREC block, which immediately follows the END STORE statement. This is easier for coding because you do not need to again specify the file specification of the STORE RECORD statement. It is also more efficient because an actual FRN statement is not necessary.</p>
This form of the STORE RECORD statement is used to add new records to any file that does not have the sorted or hashed option.</p>
<b>Sort or hash key files</b>
<p>
<p>If you are adding a record to a file that has the sort or hash option, the sort or hash key value follows the STORE RECORD on the same line, as shown below:                      </p>
The STORE RECORD statement is supported in remote file and scattered group contexts.</p>
<p class="syntax">STORE RECORD [<span class="term">sort or hash key value</span>]  
<p>
The THEN CONTINUE statement allows for the conditional building of a <var class="product">Model&nbsp;204</var> record. You can use any intervening statements after THEN CONTINUE and before END STORE.</p>
<p>
The statements following the THEN CONTINUE statement of the STORE RECORD block operate as if they were coded within a FRN $CURREC block, which immediately follows the END STORE statement. This is easier for coding because you do not need to again specify the file specification of the STORE RECORD statement. It is also more efficient because an actual FRN statement is not necessary.</p>
====Sort or hash key files====
<p>
If you are adding a record to a file that has the sort or hash option, the sort or hash key value follows the STORE RECORD on the same line, as shown below:                      </p>
<p class="syntax">STORE RECORD [<span class="term">sort or hash key value</span>]
</p>
</p>
<p>The sort or hash key must be provided if the FILEORG parameter was set to indicate that the sort or hash key is required in every record. For more information refer to the [[FILEORG parameter]].  </p>
<p>
<p>For example, the request to store a record in a file that requires the vehicle identification number as the sort key can be written:</p>
The sort or hash key must be provided if the FILEORG parameter was set to indicate that the sort or hash key is required in every record. For more information refer to the [[FILEORG parameter]].  </p>
<b>Example</b>
<p>
For example, the request to store a record in a file that requires the vehicle identification number as the sort key can be written:</p>
====Example====
<p class="code">BEGIN
<p class="code">BEGIN
STORE RECORD A99999998E
STORE RECORD A99999998E
Line 572: Line 725:
   MODEL = FOCUS
   MODEL = FOCUS
END STORE
END STORE
END  
END
</p>
</p>
<p>When this record is stored, the field VIN = A99999998E is added to it.      </p>
<p>
<p>You can also specify the sort or hash key as an expression.</p>
When this record is stored, the field VIN = A99999998E is added to it.      </p>
<b>Example</b>
<p>
You can also specify the sort or hash key as an expression.</p>
====Example====
<p class="code">IN TEST1 STORE RECORD (expression)
<p class="code">IN TEST1 STORE RECORD (expression)
...
...
END STORE
END STORE
</p>
</p>
<p>Where: </p>
<p>
<p>(expression) is the sort or hash key. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
Where: </p>
<b>Files with a UNIQUE field</b>
<p>
<p>If a record is added to the file that has a UNIQUE field, and a uniqueness conflict is detected during the STORE RECORD processing, the partially stored record is backed out. For files without the Reuse Record Number (RRN) option, this results in the use of a record number which cannot be reclaimed. </p>
(expression) is the sort or hash key. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.</p>
<b>IN GROUP MEMBER clause</b>
<p>You can use the IN GROUP MEMBER clause to restrict the STORE RECORD statement to one member file in a group context. See [[Files, groups, and reference context#IN GROUP MEMBER clause|IN GROUP MEMBER clause]] for more information.</p>
====Files with a UNIQUE field====
<b>FIND ALL VALUES options</b>
<p>
<p>Like other FIND statements, you can specify a range of values for the FIND ALL VALUES statement by using the FROM and TO clauses. </p>
If a record is added to the file that has a UNIQUE field, and a uniqueness conflict is detected during the STORE RECORD processing, the partially stored record is backed out. For files without the Reuse Record Number (RRN) option, this results in the use of a record number which cannot be reclaimed. </p>
<p>In addition, you can select values based upon a pattern by using the LIKE clause.    </p>
<p>You can store Large Object data in <var class="product">Model&nbsp;204</var> using a STORE RECORD statement as shown in the following example:</p>
====IN GROUP MEMBER clause====
<b>Handling Large Object data</b>
<p>
<p>When you store an instance of a Large Object field, the value of the data is stored in the file's Table E. Additionally, a LOB descriptor containing a pointer to the value in Table E, as well as other items, is stored in the record data in a Table B entry. The LOB descriptor is 27 bytes in length, plus the 1-byte length and 2-byte field code that apply to all fields--unless the field is preallocated. See the Rocket <var class="product">Model&nbsp;204</var> File Manager's Guide for a description on how to build a Large Object data descriptor.</p>
You can use the IN GROUP MEMBER clause to restrict the STORE RECORD statement to one member file in a group context. See [[Files, groups, and reference context#IN GROUP MEMBER clause|IN GROUP MEMBER clause]] for more information.</p>
<p>The following compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.</p>
====FIND ALL VALUES options====
<p>
Like other FIND statements, you can specify a range of values for the FIND ALL VALUES statement by using the FROM and TO clauses. </p>
<p>
In addition, you can select values based upon a pattern by using the LIKE clause.    </p>
<p>
You can store Large Object data in <var class="product">Model&nbsp;204</var> using a STORE RECORD statement as shown in the following example:</p>
====Handling Large Object data====
<p>
When you store an instance of a Large Object field, the value of the data is stored in the file's Table E. Additionally, a LOB descriptor containing a pointer to the value in Table E, as well as other items, is stored in the record data in a Table B entry. The LOB descriptor is 27 bytes in length, plus the 1-byte length and 2-byte field code that apply to all fields &mdash; unless the field is preallocated.
See [[File Load utility#Building a Large Object descriptor|Building a Large_Object descriptor]]
for a description of how to build a Large Object data descriptor.</p>
<p>
The following compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.</p>
<p class="code">M204.0037: INVALID SYNTAX
<p class="code">M204.0037: INVALID SYNTAX
</p>
</p>
<b>Storing Large Object data in segmented fashion</b>
<p>If you have Large Object data that is larger than the greatest amount of data that you want to transport to your application at one time, consider using code similar to the following.</p>
====Storing Large Object data in segmented fashion====
<p>
If you have Large Object data that is larger than the greatest amount of data that you want to transport to your application at one time, consider using code similar to the following.</p>
<p class="code">BEGIN
<p class="code">BEGIN
IMAGE BLOBDATA
IMAGE BLOBDATA
Line 632: Line 805:
END
END
</p>
</p>
<p>Remember when using the RESERVE n BYTES clause that each Large Object data implicitly has the contiguous characteristic.</p>
<p>
<p>So, if you have only a piece of the data that represents only a portion of the entire object, when you add or store the object you must reserve the full amount of contiguous space that the complete object will consume. The STORE or ADD support knows how long the piece of initial data is from the BUFFER reference, but also needs to know what the total length of the complete object will be.</p>
Remember when using the RESERVE n BYTES clause that each Large Object data implicitly has the contiguous characteristic.</p>
<b>Support for nested STOREs</b>
<p>
<p>The THEN CONTINUE block allows for the coding of a nested STORE..END STORE block within the body of the outer STORE, so that related records may be built together. The nested STORE(s) can refer to a different file context, without compromising the file context of the outer STORE. </p>
So, if you have only a piece of the data that represents only a portion of the entire object, when you add or store the object you must reserve the full amount of contiguous space that the complete object will consume. The STORE or ADD support knows how long the piece of initial data is from the BUFFER reference, but also needs to know what the total length of the complete object will be.</p>
<b>Example</b>
<p>The following example stores an order header record along with an order line record.</p>
====Support for nested STOREs====
<p>
The THEN CONTINUE block allows for the coding of a nested STORE..END STORE block within the body of the outer STORE, so that related records may be built together. The nested STORE(s) can refer to a different file context, without compromising the file context of the outer STORE. </p>
====Example====
<p>
The following example stores an order header record along with an order line record.</p>
<p class="code">IN ORDHDR STORE RECORD
<p class="code">IN ORDHDR STORE RECORD
   ORDER_NUMBER = 1000568
   ORDER_NUMBER = 1000568
Line 651: Line 830:
...
...
</p>
</p>
<p>The results of this would be the following record stored in the ORDHDR file:</p>
<p>
The results of this would be the following record stored in the ORDHDR file:</p>
<p class="code">ORDER_NUMBER = 1000568
<p class="code">ORDER_NUMBER = 1000568
CUSTOMER_NUMBER = 111456
CUSTOMER_NUMBER = 111456
ORDER_STATUS = A
ORDER_STATUS = A
</p>
</p>
<p>and the following record stored in the ORDLINE file:</p>
<p>
and the following record stored in the ORDLINE file:</p>
<p class="code">ORDER_NUMBER = 1000568
<p class="code">ORDER_NUMBER = 1000568
ITEM_ID = F004
ITEM_ID = F004
ITEM_QTY = 3
ITEM_QTY = 3
</p>
</p>
<b>Support for multiply occurring fields</b>
<p>In the following example a For Each Occurrence loop is driven, based on occurrences of the field SALES_MM previously stored, to store occurrences of MONTHLY_TOTAL:</p>
====Support for multiply occurring fields====
<p>
In the following example a For Each Occurrence loop is driven, based on occurrences of the field SALES_MM previously stored, to store occurrences of MONTHLY_TOTAL:</p>
<p class="code">B
<p class="code">B
%MONTHLY_SALES IS FLOAT ARRAY (3)
%MONTHLY_SALES IS FLOAT ARRAY (3)
Line 681: Line 864:
END
END
</p>
</p>
<p>The resultant record in the SALES file is:</p>
<p>
The resultant record in the SALES file is:</p>
<p class="code">RECTYPE = TOT_SALES
<p class="code">RECTYPE = TOT_SALES
SALES_MM = 01
SALES_MM = 01
Line 690: Line 874:
MONTHLY_TOTAL = 35
MONTHLY_TOTAL = 35
</p>
</p>
<b>Support for COMMIT and BACKOUT</b>
<p>The COMMIT and BACKOUT statements can be used following a THEN CONTINUE statement to save parts of a record as it is built, and to back out all of parts of a record conditionally. In the following example:</p>
====Support for COMMIT and BACKOUT====
<p>
The COMMIT and BACKOUT statements can be used following a THEN CONTINUE statement to save parts of a record as it is built, and to back out all of parts of a record conditionally. In the following example:</p>
<p class="code">%CUSTNO = '100639'
<p class="code">%CUSTNO = '100639'
IN ORDERS STORE RECORD
IN ORDERS STORE RECORD
Line 709: Line 895:
   ADD ADDRESS = %ADDRESS
   ADD ADDRESS = %ADDRESS
   ADD CITY = %CITY
   ADD CITY = %CITY
 
   COMMIT /? Save the customer address ?/
   COMMIT /? Save the customer address ?/
   ADD DELIV_DATE = ($DATECHG('YYYYMMDD',$DATE(1,''),10))
   ADD DELIV_DATE = ($DATECHG('YYYYMMDD',$DATE(1,''),10))
Line 717: Line 903:
END STORE
END STORE
</p>
</p>
<p>if %ORDER_DELAYED is not 'Y' then the record is stored as follows:</p>
<p>
if %ORDER_DELAYED is not 'Y' then the record is stored as follows:</p>
<p class="code">RECTYPE = ORDER
<p class="code">RECTYPE = ORDER
ORDER_NUMBER = 1000234
ORDER_NUMBER = 1000234
Line 725: Line 912:
DELIV_DATE = 20111228
DELIV_DATE = 20111228
</p>
</p>
<p>otherwise the DELIV_DATE f-v pair is backed out.</p>
<p>
<b>Known restrictions or limitations</b>
otherwise the DELIV_DATE f-v pair is backed out.</p>
====Known restrictions or limitations====
<ul>
<ul>
<li>Be cautious of using the JUMP TO statement following THEN CONTINUE to jump to a label outside the STORE..END STORE block, as this may lead to the storing of a partial record.</li>
<li>Be cautious of using the JUMP TO statement following THEN CONTINUE to jump to a label outside the STORE..END STORE block, as this may lead to the storing of a partial record.</li>
Line 735: Line 924:
<li>A DELETE RECORD statement following THEN CONTINUE, but before END STORE, will cause the current record context to be lost. Any further update statements will cause the request to be cancelled with one of the following messages:</li>
<li>A DELETE RECORD statement following THEN CONTINUE, but before END STORE, will cause the current record context to be lost. Any further update statements will cause the request to be cancelled with one of the following messages:</li>
<p class="code">M204.1233: DFAV, BAD RECORD NUMBER n FOR FILE filename
<p class="code">M204.1233: DFAV, BAD RECORD NUMBER n FOR FILE filename
 
M204.1266: NONEXISTENT RECORD REFERENCED - n IN FILE DSNLIST
M204.1266: NONEXISTENT RECORD REFERENCED - n IN FILE DSNLIST
</p></li>
</p></li>
</ul>
</ul>
<p class="note"><b>Note:</b> When using THEN CONTINUE, keep in mind standard considerations for coding any update unit. Be aware that creating longer update units has implications for resource sharing, checkpoints, and recovery requirements.</p>
<p class="note"><b>Note:</b> When using THEN CONTINUE, keep in mind standard considerations for coding any update unit. Be aware that creating longer update units has implications for resource sharing, checkpoints, and recovery requirements.</p>
 
===UPDATE RECORD statement===
==UPDATE RECORD statement==
<b>Purpose</b>
<p>Improve performance in remote context by using only one network call to perform all of a group of field-level updates (ADD, CHANGE, DELETE) against the current record in a record loop.</p>
====Purpose====
<b>Syntax</b>
<p>
<p>The syntax of the UPDATE RECORD statement is as follows:</p>
Improve performance in remote context by using only one network call to perform all of a group of field-level updates (ADD, CHANGE, DELETE) against the current record in a record loop.</p>
<p class="code">UPDATE RECORD
  update-statement-1
====Syntax====
  update-statement-2
<p>
The syntax of the UPDATE RECORD statement is as follows:</p>
<p class="syntax">UPDATE RECORD
  <span class="term">update-statement-1</span>
  <span class="term">update-statement-2</span>
   .
   .
   .
   .
   .
   .
  update-statement-N
  <span class="term">update-statement-N</span>
END UPDATE
END UPDATE
</p>
</p>
<b>Where</b>
Where:
<p>update-statements are one of the following:</p>
<p>
update-statements are one of the following:</p>
<ul>
<ul>
<li>ADD</li>
<li>ADD</li>
Line 767: Line 961:
</li>
</li>
</ul>
</ul>
<b>Usage</b>
<p>The UPDATE RECORD statement, while supported in all reference contexts, is intended for use with Parallel Query Option/204.</p>
====Usage====
<p>If a series of update statements is executed individually, each one requires a separate network call.</p>
<p>
<p>All forms of the update-statements are supported. Except, a DELETE EACH statement is not allowed within an UPDATE RECORD statement.</p>
The UPDATE RECORD statement, while supported in all reference contexts, is intended for use with Parallel Query Option/204.</p>
<p>If a field constraint violation occurs, the entire UPDATE statement is backed out.</p>
<p>
<p>If an ON unit invoked during the processing of an UPDATE RECORD statement is run with a BYPASS statement, the processing of the request continues with the statement that follows the END UPDATE statement.</p>
If a series of update statements is executed individually, each one requires a separate network call.</p>
<p>If no updates are found between UPDATE RECORD and END UPDATE, the statement is ignored.</p>
<p>
===Deleting fields and records===
All forms of the update-statements are supported. Except, a DELETE EACH statement is not allowed within an UPDATE RECORD statement.</p>
<p>This section expands on the detail of use for the DELETE statements. Some general issues related to deleting fields and records are presented.</p>
<p>
====Reused space====
If a field constraint violation occurs, the entire UPDATE statement is backed out.</p>
<p>Space recovered from both record and field deletions is always used to expand existing records that are near the deletions, regardless of which file option is selected. <var class="product">Model&nbsp;204</var> inserts new records in space recovered from deleted records only on unordered or hash files, or on sort files for which the Reuse Record Number option of the FILEORG parameter is set active (see the Rocket <var class="product">Model&nbsp;204</var> Parameter and Command Reference Manual, "FILEORG: File organization").                 </p>
<p>
<p>If the Reuse Record Number option is active for an unordered, hash, or sort file, you must explicitly delete any INVISIBLE fields associated with a record in the file when deleting the record itself. If an INVISIBLE field is not deleted, it becomes part of any new record that is put into the old record's space.    </p>
If an ON unit invoked during the processing of an UPDATE RECORD statement is run with a BYPASS statement, the processing of the request continues with the statement that follows the END UPDATE statement.</p>
====Possible error messages====
<p>
<p>Error messages might be generated when a FOR EACH RECORD loop is performed on a list of records of which some of the records have been deleted from the file. For example:</p>
If no updates are found between UPDATE RECORD and END UPDATE, the statement is ignored.</p>
==Deleting fields and records==
<p>
This section expands on the detail of use for the DELETE statements. Some general issues related to deleting fields and records are presented.</p>
===Reused space===
<p>
Space recovered from both record and field deletions is always used to expand existing records that are near the deletions, regardless of which file option is selected.
<var class="product">Model&nbsp;204</var> inserts new records in space recovered from deleted records only on unordered or hash files, or on sort files for which the Reuse Record Number option of the <var>[[FILEORG parameter|FILEORG]]</var> parameter is set active.   </p>
<p>
If the Reuse Record Number option is active for an unordered, hash, or sort file, you must explicitly delete any INVISIBLE fields associated with a record in the file when deleting the record itself. If an INVISIBLE field is not deleted, it becomes part of any new record that is put into the old record's space.    </p>
===Possible error messages===
<p>
Error messages might be generated when a FOR EACH RECORD loop is performed on a list of records of which some of the records have been deleted from the file. For example:</p>
<p class="code">BEGIN
<p class="code">BEGIN
<b></b>*
<b></b>*
Line 796: Line 1,005:
               STATE CODE = MA OR NH
               STATE CODE = MA OR NH
             END FIND
             END FIND
 
FOR EACH RECORD IN REMOVE
FOR EACH RECORD IN REMOVE
               DELETE RECORD
               DELETE RECORD
Line 806: Line 1,015:
               CHANGE SURCHARGE RATE TO .50
               CHANGE SURCHARGE RATE TO .50
             END FOR
             END FOR
END  
END
</p>
</p>
<p>would produce these messages:</p>
<p>
would produce these messages:</p>
<p class="code"><b></b>*** M204.1266: NONEXISTENT RECORD REFERENCED - 23 IN FILE INSURE
<p class="code"><b></b>*** M204.1266: NONEXISTENT RECORD REFERENCED - 23 IN FILE INSURE
<b></b>*** M204.1266: NONEXISTENT RECORD REFERENCED - 24 IN FILE INSURE
<b></b>*** M204.1266: NONEXISTENT RECORD REFERENCED - 24 IN FILE INSURE
</p>
</p>
<p>Depending upon the intent of the request, these messages may or may not indicate an error. </p>
<p>
 
Depending upon the intent of the request, these messages may or may not indicate an error. </p>
===Using NOTE values in data maintenance statements===
 
====VALUE IN label clause====
==Using NOTE values in data maintenance statements==
<p>The clause VALUE IN label can replace an explicit field value in any of the following data maintenance statements. This also applies to the special forms of these statements that are discussed in [[Operations on multiply occurring fields]].</p>
<b>Syntax</b>
===VALUE IN label clause===
<p>The forms of the VALUE IN statement are:</p>
<p>
The clause VALUE IN label can replace an explicit field value in any of the following data maintenance statements. This also applies to the special forms of these statements that are discussed in [[Operations on multiply occurring fields]].</p>
====Syntax====
<p>
The forms of the VALUE IN statement are:</p>
<p class="code">ADD fieldname = VALUE IN label
<p class="code">ADD fieldname = VALUE IN label
 
CHANGE fieldname TO VALUE IN label
CHANGE fieldname TO VALUE IN label
 
STORE RECORD fieldname = VALUE IN label  
STORE RECORD fieldname = VALUE IN label
</p>
</p>
<b>Example</b>
<p>The following request finds all records in the CLIENTS file that are registered in Alexandria and insured by agent Casola. The policy number for each record found is noted and a corresponding policy number is located on the VEHICLES file. The vehicle premium for the policy on the VEHICLES file is then changed to the total premium amount noted for the policy on the CLIENTS file.    </p>
====Example====
<p>
The following request finds all records in the CLIENTS file that are registered in Alexandria and insured by agent Casola. The policy number for each record found is noted and a corresponding policy number is located on the VEHICLES file. The vehicle premium for the policy on the VEHICLES file is then changed to the total premium amount noted for the policy on the CLIENTS file.    </p>
<p class="code">BEGIN
<p class="code">BEGIN
FIND.RECS:  IN CLIENTS FIND ALL RECORDS FOR WHICH
FIND.RECS:  IN CLIENTS FIND ALL RECORDS FOR WHICH
Line 846: Line 1,063:
END
END
</p>
</p>
===Storing data in fields===
====Storing null values====
==Storing data in fields==
<p>If the new value in an ADD, CHANGE, or STORE statement is left blank, no field is added to or stored with the record. If a field containing a null value must be added, you specify the value as an explicit null string (two single quotes with no space between them). For example:  </p>
===Storing null values===
<p>
If the new value in an ADD, CHANGE, or STORE statement is left blank, no field is added to or stored with the record. If a field containing a null value must be added, you specify the value as an explicit null string (two single quotes with no space between them). For example:  </p>
<p class="code">ADD VEHICLE PREMIUM = ''
<p class="code">ADD VEHICLE PREMIUM = ''
CHANGE AGENT TO ''  
CHANGE AGENT TO ''
</p>
</p>
<p>Note that this statement:</p>
<p>
<p class="code">CHANGE FULLNAME TO  
Note that this statement:</p>
<p class="code">CHANGE FULLNAME TO
</p>
</p>
<p>is equivalent to:</p>
<p>
<p class="code">DELETE FULLNAME  
is equivalent to:</p>
<p class="code">DELETE FULLNAME
</p>
</p>
<p>because the old value of FULLNAME is deleted, but no new value is added.</p>
<p>
 
because the old value of FULLNAME is deleted, but no new value is added.</p>
====Using the FIND statement to select fields with null values====
<p>You can use the FIND statement to select records that have a field whose value is the null string, as illustrated below:</p>
===Using the FIND statement to select fields with null values===
<p>
You can use the FIND statement to select records that have a field whose value is the null string, as illustrated below:</p>
<p class="code">FIND.RECS: IN CLIENTS FIND ALL RECORDS FOR WHICH
<p class="code">FIND.RECS: IN CLIENTS FIND ALL RECORDS FOR WHICH
               FULLNAME = ''
               FULLNAME = ''
END FIND  
END FIND
</p>
</p>
<p>However, the FIND statement does not select records for a particular field that is missing altogether from the record. See [[Record retrievals#IS PRESENT condition|IS PRESENT condition]] and [[Value loops#Locating records missing a particular field|Locating records missing a particular field]] for examples of finding records without a particular field.  </p>
<p>
 
However, the FIND statement does not select records for a particular field that is missing altogether from the record. See [[Record retrievals#IS PRESENT condition|IS PRESENT condition]] and [[Value loops#Locating records missing a particular field|Locating records missing a particular field]] for examples of finding records without a particular field.  </p>
====Storing values in preallocated fields====
<p>The file manager can indicate in a field definition the length of the field (LENGTH attribute) and/or the number of times that field can occur in a record (OCCURS attribute). Space for fields with the LENGTH and OCCURS attributes is preallocated in each record in a file, and this space cannot be expanded. </p>
<p>If you attempt to store more values (an OCCURS violation) or longer values (a LENGTH violation) than a field's definition permits, an error message is displayed or the request is cancelled. </p>
===Storing values in preallocated fields===
<b>LENGTH violations</b>
<p>
<p>If a field is defined as having a particular length (LENGTH m), that field can store only values that are between one and m bytes long. Other values are rejected. If you explicitly specify a field name and value in a User Language statement, as in this request:          </p>
The file manager can indicate in a field definition the length of the field (LENGTH attribute) and/or the number of times that field can occur in a record (OCCURS attribute). Space for fields with the LENGTH and OCCURS attributes is preallocated in each record in a file, and this space cannot be expanded. </p>
<p class="code">ADD YEAR = 90                        
<p>
If you attempt to store more values (an OCCURS violation) or longer values (a LENGTH violation) than a field's definition permits, an error message is displayed or the request is cancelled. </p>
====LENGTH violations====
<p>
If a field is defined as having a particular length (LENGTH m), that field can store only values that are between one and m bytes long. Other values are rejected. If you explicitly specify a field name and value in a User Language statement, as in this request:          </p>
<p class="code">ADD YEAR = 90
</p>
</p>
<p><var class="product">Model&nbsp;204</var> checks the length of the value during the compilation phase. A length violation detected in an update statement (ADD, CHANGE, FILE, or STORE) results in a compilation error. A length violation also can be detected for a STORE statement for a sort or hash key defined with LENGTH m. </p>
<p>
<p>If field name variables or %variables are used in an update statement, length validity checks are deferred until the request is evaluated. If an error is detected at this point, the request is cancelled. Request cancellation can be avoided by using [[$FLDLEN#$FLDLEN|$FLDLEN]]. Specifying a field value that is too long for a LENGTH field in a retrieval context always causes the retrieval to fail, because the value could not have been stored.                                  </p>
<var class="product">Model&nbsp;204</var> checks the length of the value during the compilation phase. A length violation detected in an update statement (ADD, CHANGE, FILE, or STORE) results in a compilation error. A length violation also can be detected for a STORE statement for a sort or hash key defined with LENGTH m. </p>
<p>Attempts to locate invalid values are treated as references to a nonexistent value. For example, a selection criterion in a FIND fieldname = value fails to locate any records.            </p>
<p>
<b>OCCURS violations</b>
If field name variables or %variables are used in an update statement, length validity checks are deferred until the request is evaluated. If an error is detected at this point, the request is cancelled. Request cancellation can be avoided by using [[$FLDLEN#$FLDLEN|$FLDLEN]]. Specifying a field value that is too long for a LENGTH field in a retrieval context always causes the retrieval to fail, because the value could not have been stored.                                  </p>
<p>If a field is defined as occurring a particular number of times (OCCURS n), it can be stored up to n times in any record. An attempt to add (using ADD or STORE RECORD statement) an additional occurrence to a record containing the maximum number causes the request to be cancelled. To protect User Language requests from cancellations due to occurrence violations refer to:</p>
<p>
Attempts to locate invalid values are treated as references to a nonexistent value. For example, a selection criterion in a FIND fieldname = value fails to locate any records.            </p>
====OCCURS violations====
<p>
If a field is defined as occurring a particular number of times (OCCURS n), it can be stored up to n times in any record. An attempt to add (using ADD or STORE RECORD statement) an additional occurrence to a record containing the maximum number causes the request to be cancelled. To protect User Language requests from cancellations due to occurrence violations refer to:</p>
<ul>
<ul>
<li>[[Operations on multiply occurring fields#COUNT OCCURRENCES OF statement|COUNT OCCURRENCES OF statement]] </li>
<li>[[Operations on multiply occurring fields#COUNT OCCURRENCES OF statement|COUNT OCCURRENCES OF statement]] </li>
Line 886: Line 1,121:
</li>
</li>
</ul>
</ul>
 
====Storing values in FLOAT fields====
===Storing values in FLOAT fields===
<b>Exponent notation</b>
<p>If a new value is to be stored in a field defined with the FLOAT attribute, the value can be defined in exponent notation. See [[Record retrievals#Exponent notation|Exponent notation]] for information.              </p>
====Exponent notation====
<p>An invalid value is stored as an unconverted string.</p>
<p>
<b>String values</b>
If a new value is to be stored in a field defined with the FLOAT attribute, the value can be defined in exponent notation. See [[Record retrievals#Exponent notation|Exponent notation]] for information.              </p>
<p>When you supply a string as the value to be stored, <var class="product">Model&nbsp;204</var> attempts to convert the string to floating point representation according to the floating point conversion rules (see [[Record retrievals#Equality retrievals|Equality retrievals]]). If the value to be stored cannot be converted, one of two things happens:</p>
<p>
An invalid value is stored as an unconverted string.</p>
====String values====
<p>
When you supply a string as the value to be stored, <var class="product">Model&nbsp;204</var> attempts to convert the string to floating point representation according to the floating point conversion rules (see [[Record retrievals#Equality retrievals|Equality retrievals]]). If the value to be stored cannot be converted, one of two things happens:</p>
<ul>
<ul>
<li>If the field is preallocated, the request is cancelled.</li>
<li>If the field is preallocated, the request is cancelled.</li>
Line 899: Line 1,139:
</li>
</li>
</ul>
</ul>
<b>Floating point values</b>
<p>When you supply a floating point value as the value to be stored, the value is not altered if its length is the same as the floating point field's defined length. Values of different lengths are truncated or rounded according to the rules described in. </p>
====Floating point values====
 
<p>
====Storing values in BINARY fields====
When you supply a floating point value as the value to be stored, the value is not altered if its length is the same as the floating point field's defined length. Values of different lengths are truncated or rounded according to the rules described in. </p>
<b>Compressed values</b>
<p>Fields defined as having the BINARY, OCCURS, and NON-CODED attributes can store only compressible values because only a small amount of space is preallocated for such a field. A compressible value is a decimal integer of up to nine digits with no plus sign, leading zeros, embedded blanks (following a minus sign), or decimal point. Refer to the Rocket <var class="product">Model&nbsp;204</var> File Manager's Guide for additional information on such values. </p>
===Storing values in BINARY fields===
<b>Value checking</b>
<p>Values to be stored in BINARY fields are not checked until the request is evaluated. If you attempt to store an incompressible value in a BINARY, OCCURS, and NON-CODED field, the request is cancelled. </p>
====Compressed values====
 
<p>
Fields defined as having the BINARY, OCCURS, and NON-CODED attributes can store only compressible values because only a small amount of space is preallocated for such a field. A compressible value is a decimal integer of up to nine digits with no plus sign, leading zeros, embedded blanks (following a minus sign), or decimal point.
Refer to [[Field design (File management)#Data_typing|Data typing]] for additional information on such values. </p>
====Value checking====
<p>
Values to be stored in BINARY fields are not checked until the request is evaluated. If you attempt to store an incompressible value in a BINARY, OCCURS, and NON-CODED field, the request is cancelled. </p>
==Updating field groups==
==Updating field groups==
<p class="note"><b>Note: </b>Field groups are supported as of Model 204 version 7.5.</p>
<p class="note"><b>Note: </b>Field groups are supported as of Model 204 version 7.5.</p>
 
<p>When a field group is added, a field group ID is assigned to the field group. This field group ID is unique among all field groups in the record, whether or not they have the same field group name. The ID is a number between 1 (zero is not used as an ID) and 2**32-1. The field group ID is an unsigned 32-bit integer, though only a length byte and trailing non-zero bytes are stored.</p>
<p>
 
When a field group is added, a field group ID is assigned to the field group. This field group ID is unique among all field groups in the record, whether or not they have the same field group name. The ID is a number between 1 (zero is not used as an ID) and 2**32-1. The field group ID is an unsigned 32-bit integer, though only a length byte and trailing non-zero bytes are stored.</p>
Field group IDs from 1-255 require two bytes for the field group ID in Table B, IDs 256-65535 require three bytes, and so on. Once assigned, a field group ID is not reused regardless of whether the field group associated with the ID is deleted. That is, if you add a field group and it is assigned ID 6, and then you delete the field group, ID 6 will not be reused.
Field group IDs from 1-255 require two bytes for the field group ID in Table B, IDs 256-65535 require three bytes, and so on. Once assigned, a field group ID is not reused regardless of whether the field group associated with the ID is deleted. That is, if you add a field group and it is assigned ID 6, and then you delete the field group, ID 6 will not be reused.
 
The one exception when field group ID reuse is allowed is on transaction back out. If field group ID 6 is assigned to an added field group, but then the addition is backed out, field group ID 6 can be assigned to a subsequent ADD or INSERT FIELDGROUP.
The one exception when field group ID reuse is allowed is on transaction back out. If field group ID 6 is assigned to an added field group, but then the addition is backed out, field group ID 6 can be assigned to a subsequent ADD or INSERT FIELDGROUP.
 
===Adding a field group===
===Adding a field group===
To add a field group, issue an ADD FIELDGROUP statement in a record context:
To add a field group, issue an ADD FIELDGROUP statement in a record context:
Line 922: Line 1,170:
FR IN LABELX
FR IN LABELX
   ADD FIELDGROUP <span class="term">fieldgroupname</span>
   ADD FIELDGROUP <span class="term">fieldgroupname</span>
       field1 = (<span class="term">value1</span> | <span class="term">expression</span>)
       field1 = (<span class="term">value1</span> <span class="squareb">|</span> <span class="term">expression</span>)
       [field2 = (<span class="term">value2</span> | <span class="term">expression</span>)
       [field2 = (<span class="term">value2</span> <span class="squareb">|</span> <span class="term">expression</span>)
       ...]
       ...]
   END ADD
   END ADD
END FOR</p>
END FOR</p>
The syntax of the <var class="term">fieldname=value</var> pairs inside an ADD FIELDGROUP statement is identical to that of a STORE RECORD statement. See also [[#Inserting a field group|Inserting a field group]].
The syntax of the <var class="term">fieldname=value</var> pairs inside an ADD FIELDGROUP statement is identical to that of a STORE RECORD statement. See also [[#Inserting a field group|Inserting a field group]].
 
In place of a value in the <var class="term">fieldname=value</var> pair, you can enter an expression. See [[#Expressions as field name values|Expressions as field name values]] for details.
In place of a value in the <var class="term">fieldname=value</var> pair, you can enter an expression. See [[#Expressions as field name values|Expressions as field name values]] for details.
 
===Inserting a field group===
===Inserting a field group===
In addition to the ADD FIELDGROUP statement, you can also issue an INSERT FIELDGROUP statement:
In addition to the ADD FIELDGROUP statement, you can also issue an INSERT FIELDGROUP statement:
Line 942: Line 1,190:
END FOR
END FOR
</p>
</p>
 
The INSERT FIELDGROUP statement has the same semantics as an INSERT FIELD statement. If the indicated occurrence of the field group is found, the new occurrence is inserted immediately before that occurrence. If it is not found, the new occurrence is added at the end of the record.
The INSERT FIELDGROUP statement has the same semantics as an INSERT FIELD statement. If the indicated occurrence of the field group is found, the new occurrence is inserted immediately before that occurrence. If it is not found, the new occurrence is added at the end of the record.
 
The inside of the INSERT block has the identical format to the STORE RECORD and ADD FIELDGROUP statements.
The inside of the INSERT block has the identical format to the STORE RECORD and ADD FIELDGROUP statements.
 
===Deleting a field group===
===Deleting a field group===
You can delete a field group several ways.
You can delete a field group several ways.
 
<b>Delete first field group occurrence in each record</b>
====Delete first field group occurrence in each record====
<p class="code">
<p class="code">
BEGIN
BEGIN
Line 959: Line 1,208:
   END FOR
   END FOR
</p>
</p>
<b>Delete all field group occurrences, if present, in one record</b>
====Delete all field group occurrences, if present, in one record====
<p class="code">
<p class="code">
BEGIN
BEGIN
Line 968: Line 1,218:
   END FOR
   END FOR
</p>
</p>
 
<b>Delete a field group without the name or ID reference</b>
====Delete a field group without the name or ID reference====
<p class="code">
<p class="code">
BEGIN
BEGIN
Line 984: Line 1,235:
   END FOR
   END FOR
</p>
</p>
<b>Delete a field group with a subscript</b>
<p>To delete the third occurrence of field group PITCHERS, you would issue the following statement:</p>
====Delete a field group with a subscript====
<p>
To delete the third occurrence of field group PITCHERS, you would issue the following statement:</p>
<p class="code">
<p class="code">
FR IN LABELX
FR IN LABELX
Line 1,006: Line 1,259:
   PAI
   PAI
END
END
 
POLICY_NUMBER = 100095
POLICY_NUMBER = 100095
POLICY_RESTRICTIONS = POLICY IS INVALID IF ...
POLICY_RESTRICTIONS = POLICY IS INVALID IF ...
Line 1,045: Line 1,298:
</p>
</p>
The lines that begin with a backslash (\) identify the start of a field group and the lines that begin with a forward slash (/) identify the end of the field group. The field group ID of the field group occurrence is indicated after the field group name on both the field group beginning and ending lines.
The lines that begin with a backslash (\) identify the start of a field group and the lines that begin with a forward slash (/) identify the end of the field group. The field group ID of the field group occurrence is indicated after the field group name on both the field group beginning and ending lines.
 
The field group IDs are not necessarily in ascending order in a record. The previous example was created by issuing INSERT statements, so the IDs are out of order.
The field group IDs are not necessarily in ascending order in a record. The previous example was created by issuing INSERT statements, so the IDs are out of order.
 
The new function [[$FIELDGROUPID]] can be used to show the field group ID.
The new function [[$FIELDGROUPID]] can be used to show the field group ID.
 
===Support for field group name variables===
===Support for field group name variables===
<p>Field group name variables are supported; for example:</p>
<p>
Field group name variables are supported; for example:</p>
<p class="code"><nowiki>IN POLICIES FRN %RECNO
<p class="code"><nowiki>IN POLICIES FRN %RECNO
   %FIELD = &#x2019;SURCHARGE%&#x2019;
   %FIELD = &#x2019;SURCHARGE%&#x2019;
Line 1,061: Line 1,315:
   END ADD FIELDGROUP VEHICLE
   END ADD FIELDGROUP VEHICLE
END FOR</nowiki></p>
END FOR</nowiki></p>
 
Field name variables that evaluate to something in an invalid field group context result in request cancellation. For example, if BARD is a field in field group PITCHERS and you issue the following statement:
Field name variables that evaluate to something in an invalid field group context result in request cancellation. For example, if BARD is a field in field group PITCHERS and you issue the following statement:
<p class="code">
<p class="code">
Line 1,069: Line 1,323:
</p>
</p>
A request cancellation is generated, because you tried to add an occurrence of field BARD outside its appropriate field group context.
A request cancellation is generated, because you tried to add an occurrence of field BARD outside its appropriate field group context.
 
[[Category:SOUL]]
[[Category:SOUL]]

Revision as of 00:24, 18 January 2014

Overview

Model 204 data are maintained and updated with a variety of statements. This topic describes data maintenance statements and special conditions regarding their usage.

Data maintenance statements

Use the following statements to perform basic data maintenance (record and field additions and updates):

Statement Action
ADD Place a new field-value pair on a record.
CHANGE Alter the value of fields in a record.
DELETE Remove fields from a record.
DELETE RECORD Remove a record from a Model 204 file; this statement reclaims space occupied by the deleted record.
DELETE RECORDS Remove sets of records from a Model 204 file; this statement executes faster than the DELETE RECORD statement but does not reclaim the space occupied by the deleted records.
FILE RECORDS UNDER Save retrieved or collected sets of record numbers for reference in later requests.
STORE RECORD Put a new record to a Model 204 file.
UPDATE RECORD Perform a series of field-level updates in a single call. This statement is intended for use with Parallel Query Option/204.

Using FOR EACH RECORD loops

The User Language data maintenance statements handle one record at a time, therefore the data maintenance statements are always part of a FOR EACH RECORD loop. The data maintenance may involve a field-value pair for the field.

Data used in examples in this topic

Each statement is discussed separately on the pages that follow. To illustrate their usage, assume that the following two records have been stored:

VIN = A99999998E VIN = X99999999Z MAKE = FORD MAKE = FORD COLOR = GREEN COLOR = RED YEAR = 88 YEAR = 04 MODEL = FOCUS MODEL = MUSTANG

ADD statement

Purpose

Add a new occurrence of a field and/or value to a record.

Syntax

The basic format of the ADD statement is:

ADD fieldname = {value | (expression)}

Where:

fieldname identifies the field in a record.

value specifies the value you want to store.

(expression) can be used in place of value to specify the resolved value at the time of evaluation. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.

Example

Referring to the two sample stored records (see Data used in examples in this topic), this request:

BEGIN FIND.RECS: FIND ALL RECORDS FOR WHICH MAKE = FORD BODY IS NOT PRESENT END FIND FOR EACH RECORD IN FIND.RECS ADD BODY = 2DR END FOR END

would change the records to:

VIN = A99999998E VIN = X99999999Z MAKE = FORD MAKE = FORD COLOR = GREEN COLOR = RED BODY = 2DR BODY = 2DR YEAR = 98 YEAR = 04 MODEL = FOCUS MODEL = MUSTANG

You can also add Large Object data to Model 204, as shown using the following syntax:

Large Object field syntax

ADD lob-name=BUFFER,position,length [RESERVE n [BYTES]]

Where:

  • lob-name specifies the field name of the Large Object data.
  • Note: you cannot use subscripts on ADD statements.

  • BUFFER specifies the Universal Buffer
  • position is a positive number specifying the offset of the first character in the buffer or Large Object data. If the position is set to a negative value, an error occurs. The position can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant.
  • RESERVE n specifies a positive number of bytes to reserve for the Large Object field value. The number of RESERVE bytes is always greater than or equal to maximum length of Large Object.
  • BYTES, optional, specifies that n applies to bytes.

Example

BEGIN IMAGE XYZ BUFF_DATA IS STRING LEN 200 END IMAGE IDENTIFY IMAGE XYZ * add LOB field with "CURRECn" to the records: FOR EACH RECORD * enter data into image item: %XYZ:BUFF_DATA = 'CURREC' WITH $CURREC * write image on the buffer: WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200 * add LOB field from buffer contents: ADD MY.LOB.FIELD=BUFFER,1,10 RESERVE 200 BYTES END FOR * print LOB data: FOR EACH RECORD * place LOB data into the buffer: BUFFER,1,200=MY.LOB.FIELD,1,200 * place contents of the buffer into image: READ IMAGE XYZ FROM BUFFER * print LOB data that has been placed into the buffer: PRINT VIN AND %XYZ:BUFF_DATA END

This code would result in adding a large object field to each record containing the text "CURREC" followed by the internal record number and this output:

A99999998E CURREC0 X99999999Z CURREC1

Usage

The ADD statement places an additional occurrence of a field-value pair on the record.

You can use the ADD statement to add any field to a record except for a sort or hash key field. You can use this statement only within a FOR EACH RECORD loop.

The ADD statement is supported in remote file and scattered group contexts.

To use the ADD statement with multiply occurring fields, see ADD statement.

For Large Object data, a compiler error is issued for ADD (and STORE) statements if the context to the right of the equal sign (=) is not a BUFFER reference.

M204.0037: INVALID SYNTAX

CHANGE statement

Purpose

Alter a record by adding a field and value pair, or altering the value of an existing field within a record.

Syntax

The basic format of the CHANGE statement is:

CHANGE fieldname [= value |(expression)] TO (newvalue |(expression))

Where:

  • fieldname specifies the name of the field to add to the record, or identify the field where the value is changed.
  • value is required only if the field has the INVISIBLE attribute. See the discussion on the INVISIBLE attribute.
  • newvalue specifies the value that overwrites the existing value for the field.
  • (expression) is resolved by the expression compiler and overwrites the existing value for the field. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.

Large Object field syntax

You can also change large object fields with the CHANGE statement using the following syntax:

CHANGE lob-fieldname,position1,length TO BUFFER position2,length

  • lob-fieldname specifies the name of the field
  • position, position1 and position2 are positive numbers specifying the offset of the first character in the buffer or Large Object data. If position, position1, or position2 is set to a negative value, an error occurs. Any positions can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant. The source and target lengths must be equal.
  • If position plus length minus one exceeds the current length of the LOB field, the intervening bytes are filled with binary 0. If the file has FILEORG X'100' on, then any final length of the LOB field is allowed. Otherwise extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.

    For example, if the buffer contains "ABCDEFGHIJKL" and the field is initially stored with:

    ADD LOB.FLD=BUFFER,1,3 RESERVE 500 BYTES

    The field would contain "ABC". If it was subsequently changed as follows:

    CHANGE LOB.FLD,5,10 TO BUFFER,1,10

    The field would then contain "ABC ABCDEFGHIJ" with position 4 being a binary zero.

  • TO BUFFER specifies the Universal Buffer. You can use BUFFER only in conjunction with a Large Object field.

Example

Referring to the two sample stored records (see Data used in examples in this topic), these statements:

BEGIN FIND.RECS: FIND ALL RECORDS FOR WHICH VIN = A99999998E OR X99999999Z END FIND FOR EACH RECORD IN FIND.RECS CHANGE COLOR TO BLUE END FOR END

cause Model 204 to change the value of the COLOR field in each record to BLUE. The two records then appear as:

VIN = A99999998E VIN = X99999999Z MAKE = FORD MAKE = FORD COLOR = BLUE COLOR = BLUE BODY = 2DR BODY = 2DR YEAR = 98 YEAR = 04 MODEL = FOCUS MODEL = MUSTANG

Example for Large Object

BEGIN IMAGE XYZ BUFF_DATA IS STRING LEN 200 END IMAGE IDENTIFY IMAGE XYZ IN JUNK FOR EACH RECORD * place LOB data into the buffer: %XYZ:BUFF_DATA = 'This is the data for VIN ' WITH VIN * write image on the buffer: WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200 * change the LOB field to the contents of the buffer: CHANGE MY.LOB.FIELD,1,50 TO BUFFER,1,50 END FOR * print LOB data: FOR EACH RECORD * place LOB data into the buffer: BUFFER,1,200=MY.LOB.FIELD,1,200 * place contents of the buffer into image: READ IMAGE XYZ FROM BUFFER * print LOB data that has been placed into the buffer: PRINT VIN AND %XYZ:BUFF_DATA END

This code results in changing the large object field in each record to the text "This is the data for VIN" followed by the VIN field and this output.

A99999998E This is the data for VIN A99999998E X99999999Z This is the data for VIN X99999999Z

Usage

You can use the CHANGE statement to change any field in a record except for a sort or hash key field.

You can use this statement only within a FOR EACH RECORD loop.

The CHANGE statement is supported in remote file and scattered group contexts.

If a CHANGE statement is applied to a record that does not contain the field to be changed, the specified field name and value are added to the record.

To use the CHANGE statement with multiply occurring fields, see CHANGE statement.

Changing Large Object fields and data

If you issue a CHANGE statement on a Large Object field to a record that does not contain the field, nothing happens. Unlike a non-Large Object field, a new occurrence of the field is not added to the record.

Extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.

Note: You cannot change the number of RESERVE bytes. Furthermore, facilities are not available to delete a portion of data or to insert data: for example, to replace 10 bytes with 25 bytes within Large Object data. When an attempt to insert or delete data is made the following error message is issued:

M204.2693: SOURCE AND TARGET LENGTH MUST BE EQUAL

All Large Object data implicitly has the contiguous characteristic. A User Language procedure can store some amount of initial data and then extend the data up to the RESERVE number of bytes with subsequent CHANGE statements. For example:

FR * add initial 10 bytes: ADD LOB.FLD=BUFFER,1,10 RESERVE 200 BYTES * add increments of 10 bytes at * positions 11, 21, 31, 41 * moving data from the buffer to the field FOR %X FROM 1 TO 4 %Y = %X WITH '1' CHANGE LOB.FLD,%Y,10 TO BUFFER,%Y,10 END FOR PAI PRINT 'LOBLEN' AND $LOBLEN(LOB.FLD) END

DELETE statement

Purpose

Remove fields from a record.

Syntax

The format of the DELETE statement is:

DELETE fieldname [= value |(expression)]

Where:

fieldname specifies the name of the field to remove from the record.

value option is required only if the field has the INVISIBLE attribute. (See the discussion in Field attributes.)

(expression) can be used in place of value to specify the resolved value at the time of evaluation. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.

Example

For example, the request on the next page directs Model 204 to remove the field BODY from the records retrieved by the FIND.RECS statement.

BEGIN FIND.RECS: FIND ALL RECORDS FOR WHICH VIN = A99999998E OR X99999999Z END FIND FOR EACH RECORD IN FIND.RECS DELETE BODY END FOR END

The records then appear as:

VIN = A99999998E VIN = X99999999Z MAKE = FORD MAKE = FORD COLOR = BLUE COLOR = BLUE YEAR = 98 YEAR = 04 MODEL = FOCUS MODEL = MUSTANG

Usage

You can use the DELETE fieldname statement on any field in a record except for a sort or hash key field. This statement can be used only within a FOR EACH RECORD loop.

If the DELETE fieldname statement is applied to a record that does not contain the field to be deleted, no action is taken on that record.

The DELETE fieldname statement is supported in remote file and scattered group contexts.

The DELETE fieldname statement supports Large Object data. Processing this statement frees the Table B and Table E data.

To use with multiply occurring fields, see DELETE statement.

DELETE RECORD statement

Purpose

Remove a record or sets of records from a Model 204 file.

Syntax

The format of the DELETE RECORD statement is:

DELETE RECORD

Example

This request deletes all records found by the FIND statement.

BEGIN FIND.RECS: FIND ALL RECORDS FOR WHICH MAKE = FORD YEAR = 96 END FIND FOR EACH RECORD IN FIND.RECS DELETE RECORD END FOR END

Usage

When you delete records with the DELETE RECORD statement, the space those records occupy may be reclaimed depending on the file order. For more information on reclaiming space, refer to Reused space.

You can use this statement only inside a FOR EACH RECORD loop.

The DELETE RECORD statement is supported in remote file and scattered group contexts.

Limitation of the date/time stamp feature deleting records

The date/time stamp feature does not include support for DELETE RECORD or DELETE RECORDS processing. DELETE RECORD or DELETE RECORDS processing must be handled by your application software.

As well, you can use logical delete techniques. However, in all forms of deleting records, it is your responsibility to maintain a log of record deletions, if you want one.

DELETE ALL RECORDS statement

Purpose

Delete sets of records from a Model 204 file.

Syntax

The forms of this statement are:

DELETE [ALL] RECORDS IN label DELETE [ALL] RECORDS ON [LIST] listname

  • The DELETE ALL RECORDS IN statement deletes a set of records located by a FIND statement.
  • The DELETE ALL RECORDS ON LIST deletes the set of records on the named list from the file.

Example

This request deletes the set of records located by the FIND statement.

BEGIN FIND.RECS: FIND ALL RECORDS FOR WHICH MAKE = FORD YEAR = 00 END FIND DELETE ALL RECORDS IN FIND.RECS END

Usage

The DELETE ALL RECORDS statement initiates fewer internal operations and therefore executes faster than the DELETE RECORD statement. However, use the DELETE RECORD statement rather than DELETE ALL RECORDS for records with ORDERED or UNIQUE fields, to ensure that values in the Ordered Index accurately reflect the contents of the data stored in Table B.

In addition, when records are deleted with the DELETE ALL RECORDS IN statement, the space they occupy is not reclaimed. When it is desirable to reclaim space to expand existing records or to insert new records, use the DELETE RECORD statement.

The DELETE ALL RECORDS statement is supported in remote file and scattered group contexts.

FILE RECORDS statement

Purpose

To file a set of records that were retrieved by a FIND statement or that were collected on a list. You can reference the set of records in later requests.

Syntax

The forms of this statement are:

FILE RECORDS IN label UNDER fieldname = value FILE RECORDS IN label UNDER fieldname = (expression) FILE RECORDS ON [LIST] listname UNDER fieldname = value

Usage

The FILE RECORDS statement adds the pair:

fieldname = value

or

fieldname = (expression)

to the specified records.

The FILE RECORDS statement is supported in remote file and scattered group contexts.

The field used in a FILE RECORDS statement must have the INVISIBLE KEY or INVISIBLE ORDERED field attributes. Refer to Field attributes for more information.

In addition, the fieldname = value pair should be unique in the file. If the pair has appeared previously in other records, either by explicit field creation or by a previous FILE RECORDS statement, inconsistencies in the file can occur. The FILE RECORDS statement creates new index entries for the fieldname = value pair, eliminating existing references.

Note: The index update generated by a FILE RECORDS UNDER statement is never deferred.

expression is enclosed in parentheses and is one of following expression types: function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression.

Example of using an expression

B %REC IS STRING LEN 3 %CT IS FLOAT %VAL1 IS FLOAT %VAL2 IS FLOAT %REC = 'REC' FOR %CT FROM 1 TO 10 IN EXPRESS STORE RECORD ORD1 = (%REC WITH %CT) ORD2 = (%CT * 2) ORD4 = (%CT * 4) END STORE COMMIT FD1: IN EXPRESS FD ORD1 EQ VALUE(%REC WITH %CT) END FIND FR FD1 CHANGE ORD2 TO (%CT * 2.1) ADD ORD3 = (%CT * 3) CHANGE ORD4 = (%CT * 4 ) TO (%CT * 4.1) DELETE ORD3 = (%CT * 3) INSERT ORD4 = (%CT * 5) END FOR FILE RECORDS IN FD1 UNDER INVORD5 = (%REC WITH %CT) END FOR PRINT 'FRV1' FRV1: IN EXPRESS FRV INVORD5 FD2: IN EXPRESS FD INVORD5 = VALUE IN FRV1 END FIND CT2: CT FD2 PRINT VALUE IN FRV1 AND COUNT IN CT2 END FOR END

Locating filed record sets

FIND statements in later requests can locate the filed set of records by using the fieldname = value pair as the retrieval condition. For example, if a set of records were filed with the statement:

SAVE.RECS: FILE RECORDS IN FIND.RECS UNDER SAVE = 1

then:

GET.RECS: FIND ALL RECORDS FOR WHICH SAVE = 1

appearing either in the same request or in a later one would locate the records again.

Using lists for filed record sets

Two sets of records retrieved by different FIND statements can be filed together under the same fieldname = value pair only if both sets are first placed on a list, and then the list is filed by one statement, as in the following:

BEGIN FIND.RECS: FIND ALL RECORDS FOR WHICH STATE = VIRGINIA AGENT = DOYLE END FIND SAVE.DOYLE: PLACE RECORDS IN FIND.RECS ON LIST COMPLIST FIND.T3S: FIND ALL RECORDS FOR WHICH STATE = VIRGINIA INCIDENT = T3 END FIND PLACE RECORDS IN FIND.T3S ON LIST COMPLIST SAVE.LIST: FILE RECORDS ON LIST COMPLIST UNDER SAVE = T3S END

If the SAVE.DOYLE statement were replaced with:

SAVE.DOYLE: FILE RECORDS IN FIND.RECS UNDER SAVE = T3S

the original references to SAVE = T3S would be lost as soon as the SAVE.LIST was executed. Thus, a second use of the same fieldname = value pair replaces the previous one.

Simulating the FILE RECORDS UNDER statement

You can simulate the FILE RECORDS statement by explicitly adding a fieldname = value pair to a set of records. For example, if the SAVE.LIST statement in the previous example is replaced by:

SAVE.LIST: FOR EACH RECORD ON LIST COMPLIST ADD SAVE = T3S END FOR

the index references to existing records that contain that fieldname = value pair are not invalidated. You are responsible for deleting such references, if deletion is desired.

STORE RECORD statement

Purpose

Use the STORE RECORD statement to add new records to a Model 204 file. The fieldname=value pairs that constitute the new record must follow the STORE RECORD statement, one to a line, and must not be labeled.

Syntax

The format of the STORE RECORD statement is:

STORE RECORD fieldname =[value1 | (expression1)] [fieldname2=[value2 | (expression2)]] . . . [THEN CONTINUE statement statement . . .] END STORE [label]

Where:

(expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.

You can also store Large Object fields to Model 204.

STORE RECORD lob-name=BUFFER,position,length [RESERVE n [BYTES]] . . . END_STORE [label]

Where:

  • lob-name specifies the field name of the Large Object field.
  • Note: you cannot use subscripts on statements for any field type.

  • BUFFER specifies the Universal Buffer
  • >position is a positive number specifying the offset of the first character in the buffer. If the position is less than one, an error occurs. The position can be a %variable or a constant.
  • >length is a positive number specifying the length to move. The length can be a %variable or a constant.
  • RESERVE >n specifies a positive number of bytes to reserve for the Large Object field value. The number of bytes is always greater than or equal to $LOBLEN.
  • BYTES, optional, specifies that n applies to bytes.

Examples

BEGIN STORE RECORD NAME = JEAN ANDERSON SALARY = 30000 POSITION = CHEMIST END STORE END

Using the THEN CONTINUE statement

%COLOR = 'BLUE' STORE RECORD MODEL = %MODEL THEN CONTINUE FR WHERE RECTYPE = 'TABLE' AND COLOR = %COLOR %CODE = COLOR_CODE END FOR ADD COLOR_CODE=%CODE PAI END STORE

Storing Large Object data

STORE RECORD NOVEL=BUFFER,%POSITION,%LENGTH [RESERVE n [BYTES]] AUTHOR_PIC=BUFFER,%POSITION2,%LENGTH2 END STORE

Using an expression

B %REC IS STRING LEN 3 %CT IS FLOAT %VAL1 IS FLOAT %VAL2 IS FLOAT %REC = 'REC' FOR %CT FROM 1 TO 10 IN EXPRESS STORE RECORD ORD1 = (%REC WITH %CT) ORD2 = (%CT * 2) ORD4 = (%CT * 4) END STORE COMMIT FD1: IN EXPRESS FD ORD1 EQ VALUE(%REC WITH %CT) END FIND FR FD1 CHANGE ORD2 TO (%CT * 2.1) ADD ORD3 = (%CT * 3) CHANGE ORD4 = (%CT * 4 ) TO (%CT * 4.1) DELETE ORD3 = (%CT * 3) INSERT ORD4 = (%CT * 5) END FOR END FOR END

Usage

Use an END STORE statement or another label to end the STORE RECORD statement. Do not end a STORE RECORD statement with an END BLOCK statement.

This form of the STORE RECORD statement is used to add new records to any file that does not have the sorted or hashed option.

The STORE RECORD statement is supported in remote file and scattered group contexts.

The THEN CONTINUE statement allows for the conditional building of a Model 204 record. You can use any intervening statements after THEN CONTINUE and before END STORE.

The statements following the THEN CONTINUE statement of the STORE RECORD block operate as if they were coded within a FRN $CURREC block, which immediately follows the END STORE statement. This is easier for coding because you do not need to again specify the file specification of the STORE RECORD statement. It is also more efficient because an actual FRN statement is not necessary.

Sort or hash key files

If you are adding a record to a file that has the sort or hash option, the sort or hash key value follows the STORE RECORD on the same line, as shown below:

STORE RECORD [sort or hash key value]

The sort or hash key must be provided if the FILEORG parameter was set to indicate that the sort or hash key is required in every record. For more information refer to the FILEORG parameter.

For example, the request to store a record in a file that requires the vehicle identification number as the sort key can be written:

Example

BEGIN STORE RECORD A99999998E MAKE = FORD COLOR = GREEN YEAR = 98 MODEL = FOCUS END STORE END

When this record is stored, the field VIN = A99999998E is added to it.

You can also specify the sort or hash key as an expression.

Example

IN TEST1 STORE RECORD (expression) ... END STORE

Where:

(expression) is the sort or hash key. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.

Files with a UNIQUE field

If a record is added to the file that has a UNIQUE field, and a uniqueness conflict is detected during the STORE RECORD processing, the partially stored record is backed out. For files without the Reuse Record Number (RRN) option, this results in the use of a record number which cannot be reclaimed.

IN GROUP MEMBER clause

You can use the IN GROUP MEMBER clause to restrict the STORE RECORD statement to one member file in a group context. See IN GROUP MEMBER clause for more information.

FIND ALL VALUES options

Like other FIND statements, you can specify a range of values for the FIND ALL VALUES statement by using the FROM and TO clauses.

In addition, you can select values based upon a pattern by using the LIKE clause.

You can store Large Object data in Model 204 using a STORE RECORD statement as shown in the following example:

Handling Large Object data

When you store an instance of a Large Object field, the value of the data is stored in the file's Table E. Additionally, a LOB descriptor containing a pointer to the value in Table E, as well as other items, is stored in the record data in a Table B entry. The LOB descriptor is 27 bytes in length, plus the 1-byte length and 2-byte field code that apply to all fields — unless the field is preallocated. See Building a Large_Object descriptor for a description of how to build a Large Object data descriptor.

The following compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.

M204.0037: INVALID SYNTAX

Storing Large Object data in segmented fashion

If you have Large Object data that is larger than the greatest amount of data that you want to transport to your application at one time, consider using code similar to the following.

BEGIN IMAGE BLOBDATA ARRAY OCCURS 25 SEG IS STRING LEN 255 END ARRAY END IMAGE %DATASIZE=6144 %TOTAL.LEN=61440 /?*---------------------------------------------------*?/ /? Get a buffer of data %DATASIZE bytes from someplace ?/ /? e.g. an IMAGE. Assume the blob data has been  ?/ /? segmented into 6144 byte segments and the complete  ?/ /? blob of 61,440 bytes is contained in ten records in ?/ /? an external sequential data set - INPUTDD.  ?/ /?*---------------------------------------------------*?/ READ IMAGE BLOBDATA FROM INPUTDD %FIRST = 1 FRN 56789 /? GET SOME RECORD  ?/ REPEAT WHILE $STATUS = 0 WRITE IMAGE BLOBDATA ON BUFFER POSITION 1 MAXLEN 6144 IF %FIRST=1 THEN ADD lob-field-name=BUFFER,1,%DATASIZE - RESERVE %TOTAL.LEN BYTES ELSE %OFFSET=(%FIRST*%DATASIZE) - %DATASIZE + 1 CHANGE lob-field-name,%OFFSET,%DATASIZE - TO BUFFER,1,%DATASIZE END IF %FIRST = %FIRST + 1 READ IMAGE BLOBDATA FROM INPUTDD END REPEAT END FOR END

Remember when using the RESERVE n BYTES clause that each Large Object data implicitly has the contiguous characteristic.

So, if you have only a piece of the data that represents only a portion of the entire object, when you add or store the object you must reserve the full amount of contiguous space that the complete object will consume. The STORE or ADD support knows how long the piece of initial data is from the BUFFER reference, but also needs to know what the total length of the complete object will be.

Support for nested STOREs

The THEN CONTINUE block allows for the coding of a nested STORE..END STORE block within the body of the outer STORE, so that related records may be built together. The nested STORE(s) can refer to a different file context, without compromising the file context of the outer STORE.

Example

The following example stores an order header record along with an order line record.

IN ORDHDR STORE RECORD ORDER_NUMBER = 1000568 CUSTOMER_NUMBER = 111456 THEN CONTINUE IN ORDLINE STORE RECORD ORDER_NUMBER = 1000568 ITEM_ID = F004 ITEM_QTY = 3 END STORE ADD ORDER_STATUS = A END STORE ...

The results of this would be the following record stored in the ORDHDR file:

ORDER_NUMBER = 1000568 CUSTOMER_NUMBER = 111456 ORDER_STATUS = A

and the following record stored in the ORDLINE file:

ORDER_NUMBER = 1000568 ITEM_ID = F004 ITEM_QTY = 3

Support for multiply occurring fields

In the following example a For Each Occurrence loop is driven, based on occurrences of the field SALES_MM previously stored, to store occurrences of MONTHLY_TOTAL:

B %MONTHLY_SALES IS FLOAT ARRAY (3) %MONTHLY_SALES(1) = 10 %MONTHLY_SALES(2) = 15 %MONTHLY_SALES(3) = 35 IN SALES STORE RECORD RECTYPE = TOT_SALES SALES_MM = '01' SALES_MM = '02' SALES_MM = '03' THEN CONTINUE FEO_SALES: FEO SALES_MM ADD MONTHLY_TOTAL = %MONTHLY_SALES(OCCURRENCE IN FEO_SALES) END FOR END STORE END

The resultant record in the SALES file is:

RECTYPE = TOT_SALES SALES_MM = 01 SALES_MM = 02 SALES_MM = 03 MONTHLY_TOTAL = 10 MONTHLY_TOTAL = 15 MONTHLY_TOTAL = 35

Support for COMMIT and BACKOUT

The COMMIT and BACKOUT statements can be used following a THEN CONTINUE statement to save parts of a record as it is built, and to back out all of parts of a record conditionally. In the following example:

%CUSTNO = '100639' IN ORDERS STORE RECORD RECTYPE = ORDER ORDER_NUMBER = 1000234 CUSTOMER_NUMBER = %CUSTNO THEN CONTINUE COMMIT /? save the order header ?/ FIND_CUST: IN CLIENTS FD RECTYPE = POLICYHOLDER POLICY NO = %CUSTNO END FIND FOR 1 RECORD IN FIND_CUST %ADDRESS = ADDRESS %CITY = CITY END FOR ADD ADDRESS = %ADDRESS ADD CITY = %CITY COMMIT /? Save the customer address ?/ ADD DELIV_DATE = ($DATECHG('YYYYMMDD',$DATE(1,),10)) IF %ORDER_DELAYED = 'Y' THEN BACKOUT /? Back out deliv date if delay detected ?/ END IF END STORE

if %ORDER_DELAYED is not 'Y' then the record is stored as follows:

RECTYPE = ORDER ORDER_NUMBER = 1000234 CUSTOMER_NUMBER = 100639 ADDRESS = 0880 HANCOCK STREET CITY = LANCASTER DELIV_DATE = 20111228

otherwise the DELIV_DATE f-v pair is backed out.

Known restrictions or limitations

  • Be cautious of using the JUMP TO statement following THEN CONTINUE to jump to a label outside the STORE..END STORE block, as this may lead to the storing of a partial record.
  • It is possible to call a subroutine after the THEN CONTINUE statement, as you might in a FOR RECORD NUMBER loop. Additional update statements to the current record are allowed in the subroutine but only in a FRN $CURREC loop. Otherwise, record context is not established and any additional updating statements within the subroutine would be rejected with the following compilation error:
  • M204.0229: INVALID STATEMENT

  • A DELETE RECORD statement following THEN CONTINUE, but before END STORE, will cause the current record context to be lost. Any further update statements will cause the request to be cancelled with one of the following messages:
  • M204.1233: DFAV, BAD RECORD NUMBER n FOR FILE filename M204.1266: NONEXISTENT RECORD REFERENCED - n IN FILE DSNLIST

Note: When using THEN CONTINUE, keep in mind standard considerations for coding any update unit. Be aware that creating longer update units has implications for resource sharing, checkpoints, and recovery requirements.

UPDATE RECORD statement

Purpose

Improve performance in remote context by using only one network call to perform all of a group of field-level updates (ADD, CHANGE, DELETE) against the current record in a record loop.

Syntax

The syntax of the UPDATE RECORD statement is as follows:

UPDATE RECORD update-statement-1 update-statement-2 . . . update-statement-N END UPDATE

Where:

update-statements are one of the following:

  • ADD
  • DELETE
  • CHANGE
  • INSERT

Usage

The UPDATE RECORD statement, while supported in all reference contexts, is intended for use with Parallel Query Option/204.

If a series of update statements is executed individually, each one requires a separate network call.

All forms of the update-statements are supported. Except, a DELETE EACH statement is not allowed within an UPDATE RECORD statement.

If a field constraint violation occurs, the entire UPDATE statement is backed out.

If an ON unit invoked during the processing of an UPDATE RECORD statement is run with a BYPASS statement, the processing of the request continues with the statement that follows the END UPDATE statement.

If no updates are found between UPDATE RECORD and END UPDATE, the statement is ignored.

Deleting fields and records

This section expands on the detail of use for the DELETE statements. Some general issues related to deleting fields and records are presented.

Reused space

Space recovered from both record and field deletions is always used to expand existing records that are near the deletions, regardless of which file option is selected. Model 204 inserts new records in space recovered from deleted records only on unordered or hash files, or on sort files for which the Reuse Record Number option of the FILEORG parameter is set active.

If the Reuse Record Number option is active for an unordered, hash, or sort file, you must explicitly delete any INVISIBLE fields associated with a record in the file when deleting the record itself. If an INVISIBLE field is not deleted, it becomes part of any new record that is put into the old record's space.

Possible error messages

Error messages might be generated when a FOR EACH RECORD loop is performed on a list of records of which some of the records have been deleted from the file. For example:

BEGIN * * FIND ALL STATE CONTROL RECORDS * STATES: FIND ALL RECORDS FOR WHICH REC = STATE END FIND PLACE RECORDS IN STATES ON LIST FOUND * * EXCLUDE MASS. AND N.H. BECAUSE * THEIR SURCHARGE RATE HAS NOT CHANGED * REMOVE: FIND ALL RECORDS ON LIST FOUND FOR WHICH STATE CODE = MA OR NH END FIND FOR EACH RECORD IN REMOVE DELETE RECORD END FOR * * CHANGE SURCHARGE RATE FOR ALL OTHER STATES * SURCHARGE: FOR EACH RECORD ON LIST FOUND CHANGE SURCHARGE RATE TO .50 END FOR END

would produce these messages:

*** M204.1266: NONEXISTENT RECORD REFERENCED - 23 IN FILE INSURE *** M204.1266: NONEXISTENT RECORD REFERENCED - 24 IN FILE INSURE

Depending upon the intent of the request, these messages may or may not indicate an error.


Using NOTE values in data maintenance statements

VALUE IN label clause

The clause VALUE IN label can replace an explicit field value in any of the following data maintenance statements. This also applies to the special forms of these statements that are discussed in Operations on multiply occurring fields.

Syntax

The forms of the VALUE IN statement are:

ADD fieldname = VALUE IN label CHANGE fieldname TO VALUE IN label STORE RECORD fieldname = VALUE IN label

Example

The following request finds all records in the CLIENTS file that are registered in Alexandria and insured by agent Casola. The policy number for each record found is noted and a corresponding policy number is located on the VEHICLES file. The vehicle premium for the policy on the VEHICLES file is then changed to the total premium amount noted for the policy on the CLIENTS file.

BEGIN FIND.RECS: IN CLIENTS FIND ALL RECORDS FOR WHICH AGENT = CASOLA CITY = ALEXANDRIA END FIND FOR EACH RECORD IN FIND.RECS KEEP.POL: NOTE POLICY NO KEEP.PREM: NOTE TOTAL PREMIUM FIND.MATCH: IN VEHICLES FIND ALL RECORDS FOR WHICH OWNER POLICY = VALUE IN KEEP.POL END FIND FOR EACH RECORD IN FIND.MATCH CHANGE VEHICLE PREMIUM TO VALUE - IN KEEP.PREM END FOR END FOR END

Storing data in fields

Storing null values

If the new value in an ADD, CHANGE, or STORE statement is left blank, no field is added to or stored with the record. If a field containing a null value must be added, you specify the value as an explicit null string (two single quotes with no space between them). For example:

ADD VEHICLE PREMIUM = CHANGE AGENT TO

Note that this statement:

CHANGE FULLNAME TO

is equivalent to:

DELETE FULLNAME

because the old value of FULLNAME is deleted, but no new value is added.

Using the FIND statement to select fields with null values

You can use the FIND statement to select records that have a field whose value is the null string, as illustrated below:

FIND.RECS: IN CLIENTS FIND ALL RECORDS FOR WHICH FULLNAME = END FIND

However, the FIND statement does not select records for a particular field that is missing altogether from the record. See IS PRESENT condition and Locating records missing a particular field for examples of finding records without a particular field.


Storing values in preallocated fields

The file manager can indicate in a field definition the length of the field (LENGTH attribute) and/or the number of times that field can occur in a record (OCCURS attribute). Space for fields with the LENGTH and OCCURS attributes is preallocated in each record in a file, and this space cannot be expanded.

If you attempt to store more values (an OCCURS violation) or longer values (a LENGTH violation) than a field's definition permits, an error message is displayed or the request is cancelled.

LENGTH violations

If a field is defined as having a particular length (LENGTH m), that field can store only values that are between one and m bytes long. Other values are rejected. If you explicitly specify a field name and value in a User Language statement, as in this request:

ADD YEAR = 90

Model 204 checks the length of the value during the compilation phase. A length violation detected in an update statement (ADD, CHANGE, FILE, or STORE) results in a compilation error. A length violation also can be detected for a STORE statement for a sort or hash key defined with LENGTH m.

If field name variables or %variables are used in an update statement, length validity checks are deferred until the request is evaluated. If an error is detected at this point, the request is cancelled. Request cancellation can be avoided by using $FLDLEN. Specifying a field value that is too long for a LENGTH field in a retrieval context always causes the retrieval to fail, because the value could not have been stored.

Attempts to locate invalid values are treated as references to a nonexistent value. For example, a selection criterion in a FIND fieldname = value fails to locate any records.

OCCURS violations

If a field is defined as occurring a particular number of times (OCCURS n), it can be stored up to n times in any record. An attempt to add (using ADD or STORE RECORD statement) an additional occurrence to a record containing the maximum number causes the request to be cancelled. To protect User Language requests from cancellations due to occurrence violations refer to:

Storing values in FLOAT fields

Exponent notation

If a new value is to be stored in a field defined with the FLOAT attribute, the value can be defined in exponent notation. See Exponent notation for information.

An invalid value is stored as an unconverted string.

String values

When you supply a string as the value to be stored, Model 204 attempts to convert the string to floating point representation according to the floating point conversion rules (see Equality retrievals). If the value to be stored cannot be converted, one of two things happens:

  • If the field is preallocated, the request is cancelled.
  • If the field is not preallocated, the unconverted value is stored.

Floating point values

When you supply a floating point value as the value to be stored, the value is not altered if its length is the same as the floating point field's defined length. Values of different lengths are truncated or rounded according to the rules described in.

Storing values in BINARY fields

Compressed values

Fields defined as having the BINARY, OCCURS, and NON-CODED attributes can store only compressible values because only a small amount of space is preallocated for such a field. A compressible value is a decimal integer of up to nine digits with no plus sign, leading zeros, embedded blanks (following a minus sign), or decimal point. Refer to Data typing for additional information on such values.

Value checking

Values to be stored in BINARY fields are not checked until the request is evaluated. If you attempt to store an incompressible value in a BINARY, OCCURS, and NON-CODED field, the request is cancelled.

Updating field groups

Note: Field groups are supported as of Model 204 version 7.5.

When a field group is added, a field group ID is assigned to the field group. This field group ID is unique among all field groups in the record, whether or not they have the same field group name. The ID is a number between 1 (zero is not used as an ID) and 2**32-1. The field group ID is an unsigned 32-bit integer, though only a length byte and trailing non-zero bytes are stored.

Field group IDs from 1-255 require two bytes for the field group ID in Table B, IDs 256-65535 require three bytes, and so on. Once assigned, a field group ID is not reused regardless of whether the field group associated with the ID is deleted. That is, if you add a field group and it is assigned ID 6, and then you delete the field group, ID 6 will not be reused.

The one exception when field group ID reuse is allowed is on transaction back out. If field group ID 6 is assigned to an added field group, but then the addition is backed out, field group ID 6 can be assigned to a subsequent ADD or INSERT FIELDGROUP.

Adding a field group

To add a field group, issue an ADD FIELDGROUP statement in a record context:

FR IN LABELX ADD FIELDGROUP fieldgroupname field1 = (value1 | expression) [field2 = (value2 | expression) ...] END ADD END FOR

The syntax of the fieldname=value pairs inside an ADD FIELDGROUP statement is identical to that of a STORE RECORD statement. See also Inserting a field group.

In place of a value in the fieldname=value pair, you can enter an expression. See Expressions as field name values for details.

Inserting a field group

In addition to the ADD FIELDGROUP statement, you can also issue an INSERT FIELDGROUP statement:

FR WHERE ... INSERT FIELDGROUP name(subscript) FIELDA = ’ABC’ FIELDB = ’DEF’ ... END INSERT END FOR

The INSERT FIELDGROUP statement has the same semantics as an INSERT FIELD statement. If the indicated occurrence of the field group is found, the new occurrence is inserted immediately before that occurrence. If it is not found, the new occurrence is added at the end of the record.

The inside of the INSERT block has the identical format to the STORE RECORD and ADD FIELDGROUP statements.

Deleting a field group

You can delete a field group several ways.


Delete first field group occurrence in each record

BEGIN A: IN TEST1 FD END FIND B: FR A DELETE FIELDGROUP BIRDS END FOR

Delete all field group occurrences, if present, in one record

BEGIN A: IN TEST1 FD END FIND B: FR A DELETE EACH FIELDGROUP PESTS END FOR


Delete a field group without the name or ID reference

BEGIN A: IN TEST1 FD END FIND B: FR A FOR EACH OCCURRENCE OF FIELDGROUP TRANSLATIONS IF LANGUAGE = ’INDIAN’ THEN %X = $FIELDGROUPID DELETE FIELDGROUP PRINT ’DELETING ID: ’ WITH %X END IF END FOR END FOR

Delete a field group with a subscript

To delete the third occurrence of field group PITCHERS, you would issue the following statement:

FR IN LABELX DELETE FIELDGROUP PITCHERS(3) END FOR

When you delete a field group occurrence, all fields within the field group occurrence are deleted, as well as the indices for those fields. Or, you can delete a field group with a simple DELETE statement while in a field group context:

FR IN LABELX FAO FIELDGROUP PITCHERS DELETE FIELDGROUP END FOR END FOR

Displaying field groups and their fields

After you add a field group to a record, you can display the field groups and their fields by issuing a PAI statement, output as follows:

BEGIN IN POLICIES FOR EACH RECORD WHERE POLICY_NUMBER = 100095 PAI END POLICY_NUMBER = 100095 POLICY_RESTRICTIONS = POLICY IS INVALID IF ... ... OTHER POLICY FIELDS \DRIVER = 1 DRIVER_NAME = ALTON, BARBARA W ...OTHER DRIVER FIELDS /DRIVER = 1 \DRIVER = 2 DRIVER_NAME = ALTON, CARRIE Y ...OTHER DRIVER FIELDS /DRIVER = 2 \VEHICLE = 6 MAKE = VOLKSWAGEN MODEL = NEW BEETLE ...OTHER VEHICLE FIELDS /VEHICLE = 6 \VEHICLE = 7 MAKE = MITSUBISHI MODEL = ECLIPSE ...OTHER VEHICLE FIELDS \CLAIM = 9 CLAIM_NUMBER = 100059 WEATHER = RAIN ...OTHER CLAIM FIELDS /CLAIM = 9 \CLAIM = 10 CLAIM_NUMBER = 100064 WEATHER = FOG ...OTHER CLAIM FIELDS /CLAIM = 10 /VEHICLE = 7 \VEHICLE = 8 MAKE = CHEVROLET MODEL = SUBURBAN ...OTHER VEHICLE FIELDS /VEHICLE = 8

The lines that begin with a backslash (\) identify the start of a field group and the lines that begin with a forward slash (/) identify the end of the field group. The field group ID of the field group occurrence is indicated after the field group name on both the field group beginning and ending lines.

The field group IDs are not necessarily in ascending order in a record. The previous example was created by issuing INSERT statements, so the IDs are out of order.

The new function $FIELDGROUPID can be used to show the field group ID.

Support for field group name variables

Field group name variables are supported; for example:

IN POLICIES FRN %RECNO %FIELD = ’SURCHARGE%’ ADD FIELDGROUP VEHICLE MAKE = ’FORD’ MODEL = ’MUSTANG’  %%FIELD = 15 * and so on END ADD FIELDGROUP VEHICLE END FOR

Field name variables that evaluate to something in an invalid field group context result in request cancellation. For example, if BARD is a field in field group PITCHERS and you issue the following statement:

IN FILE REDSOCKS FRN %RECNO %FIELD = ’BARD’ ADD %%FIELD = ’Knuckle ball’

A request cancellation is generated, because you tried to add an occurrence of field BARD outside its appropriate field group context.