Random Retrieval from a File (CHAIN)
The Random Retrieval from a File (CHAIN) command reads a record from a file and places the data from the record into the fields defined by the record format.
The record to read is identified by either a key value or a relative record number. If a key value the file must be open with ACCMTH(*KEY). The key value is specified using either the KEYLIST or KEYSTRUCT parameter. When using the KEYLIST parameter the key can be a single CL variable, a list of CL variables, a literal, or a combination of CL variables and literal values. If a relative record number is to be used the file must be open with ACCMTH(*RRN). The relative record value is specified using the RRN parameter. The RRN value can be a single CL variable or a literal value.
This command never runs in the traditional sense and will return an error if an attempt is made to run the command. The CLF precompilers, when they encounter this command in a CL source program, replace the command and generate CL instructions directly into the compiled CL program.
Restrictions:
- This command can only be used in a CL program that is created using a CLF precompiler command. The CLF precompiler commands are CRTBNDCLF, CRTCLFMOD, and CRTCLFPGM.
- The file being read must have been previously opened using either the Open File for Processing (OPEN) command or the Open File using CLF (OPNFCLF) command with USAGE(*INPUT) or USAGE(*BOTH).
| Keyword | Description | Choices | Notes |
| KEYLIST |
Key field list |
Values (up to 10 repetitions): Not restricted |
Optional, Positional 1 |
| FILEID |
File identifier |
Simple name |
Optional, Positional 2 |
| RCDFMT |
Record format |
Character value, *ONLY |
Optional |
| RCDNOTFND |
Record not found |
Logical value |
Optional |
| ERR |
Error found |
Logical value |
Optional |
| RCDLCK |
Record lock |
*OPNF, *NO |
Optional |
| KEYSTRUCT |
Key field structure |
Element list |
Optional |
| Element 1: Number of key fields |
Unsigned integer |
| Element 2: Structure |
Character value |
| RRN |
Relative record number |
Integer |
Optional |
| OPNPGM |
Program opening file |
Single values: *CURPGM Other values: Qualified object name |
Optional |
| Qualifier 1: Program opening file |
Name |
| Qualifier 2: Library |
Name, *CURLIB |
Key field list (KEYLIST)
Specifies the key values to be used when reading a record by key.
You can specify up to 10 values for this parameter. Each value specified corresponds to one key field in the file's key definition. The definition of the CL variable used does not have to match the definition of the key field within the file. The two definitions can be of different TYPE and LEN. In addition, character expressions can be used.
If the file has a composite key it is not necessary to provide all key values. Read by partial key is supported. If a file has three key fields, you can specify one, two, or all three key field values with this parameter.
When specifying numeric variables or numeric literals, any valid numeric datatype can be used. For instance the CL variable may be declared as TYPE(*DEC) while the file key field is defined as TYPE(*INT). When using numeric variables or literals the maximum number of digits at runtime that can be represented to the left of the decimal point is nine. At runtime the maximum number of digits to the right of the decimal point is five. When using a CL variable the variable can be declared with a larger size, for instance TYPE(*DEC) LEN(15 0), but at run time the actual value must be within the range of .00001 to 9999999999.99999.
If the numeric value is outside of this range the system will send message CPF0001 (Error found on READRCDCLF command) prior to running the command. For numeric keys that exceed this range you can pass the numeric value as a character value or use the KEYSTRUCT parameter. The following examples demonstrate how to use a character value for numeric keys with a value greater than 9999999999.99999.
The first example uses a character variable with a length of 30 to represent the numeric value. The second example uses a character literal to represent a numeric value of 15 digits.
/* Using a large character variable */
Dcl Var(&Char) Type(*Char) Len(30)
Dcl Var(&Dec) Type(*Dec) Len(15 0) +
Value(123456789012345)
ChgVar Var(&Char) Value(&Dec)
Chain &Char BIGKEY
/* or using a character literal value */
Chain '123456789012345' BIGKEY
You cannot specify both KEYLIST and KEYSTRUCT with the same command.
- unrestricted-value
- Specify the CL variables, or literal values, that contain the key values to be used. There must be one CL variable or literal value specified for each key field to be used.
When working with files with multiple keys you do not have to specify all key fields. Only specify those key values that you want used when reading a record. You cannot however omit key values. For example, if the file has five key fields defined and you want to specify key field 3 then you must also specify key fields 1 and 2. You do not however need to specify values for keys 4 and 5.
File identifier (FILEID)
Specifies the file identifier that was used on a previous Open File for Processing (OPEN) or Open File using CLF (OPNFCLF) command in the application.
This parameter is used by CLF commands to identify the file to be processed by the command.
If the file is declared using the DCLFCLF command this parameter is optional if the RCDFMT parameter specifies a record format name that is associated with one and only one file ID.
- simple-name
- Specify a name that matches the FILEID parameter value of a previous OPEN or OPNFCLF command.
Record format (RCDFMT)
Specifies the name of the record format to be used.
- *ONLY
- There is only one record format defined for the file. This record format will be used by the command.
- character-value
- Specify the name of the record format to be used.
Record not found (RCDNOTFND)
Specifies a logical CL variable to receive Record Not Found status. If the variable value is equal to '1' (true) then the requested record was not found when performing the read command. If the variable value is equal to '0' (false) then the requested record was found.
This CL variable is typically declared by either the Declare Indicators using CLF (DCLINDCLF) command or the Generate Indicators using CLF (GENINDCLF) command. These commands would have specified CLFIND(*YES). When using these commands the name of the declared CL variable is &RNF.
If no CL variable is specified and a record not found condition is encountered the application program will be sent escape message VC2501B.
- logical-value
- Specify the name of a CL variable declared as TYPE(*LGL).
Error found (ERR)
Specifies a CL logical variable to receive general error status. If the variable value is equal to '1' (true) then an error was found when performing the command. If the variable value is equal to '0' (false) then no error was found when performing the command.
This CL variable can be declared by the Declare Indicators using CLF (DCLINDCLF) command, the Generate Indicators using CLF (GENINDCLF) command, or by you using the Declare CL Variable (DCL) command. The two CLF commands would have specified CLFIND(*YES). When using the CLF commands the name of the CL variable is &ERR.
If no CL variable is specified and an error condition is encountered the application program will be sent an escape message.
- logical-value
- Specify the name of a CL variable declared as TYPE(*LGL).
Record lock (RCDLCK)
Specifies if the record being read should be locked.
- *OPNF
- The record being read will be locked based on the value specifed for the USAGE parameter when the file was opened. If the file is open with USAGE(*BOTH) then the record will be locked. Otherwise the record will not be locked.
- *NO
- The record will not be locked. If the job currently holds a lock on a record within the file the pre-existing lock will continue to be held. To release a pre-existing lock you can use either the Release a Record (UNLOCK) command or the Release Record using CLF (RLSRCDCLF) command.
Key field structure (KEYSTRUCT)
Specifies the key values to be used when reading a record by key.
You cannot specify KEYLIST and KEYSTRUCT with the same command.
Element 1: Number of key fields
- unsigned-integer
- Specify the number of key fields within the structure element that are to be used. If the file has a composite key it is not necessary to provide all key values. Read by partial key is supported.
Element 2: Structure
- character-value
- Specify the CL variable that contains the key values. The key fields provided in the CL variable must be declared the same as the key fields defined within the keyed access path being used.
A key field structure can be defined using either the Declare File Key Structure (DCLFKSCLF) or the Generate File Key Structure (GENFKSCLF) command.
Relative record number (RRN)
Specifies the relative record number of the record to be read.
- unsigned integer
- Specify the relative record number of the record to be read.
Program opening file (OPNPGM)
The same FILEID value can be in use across multiple programs within a job. Each instance of a file open is uniquely identifed by the OPNPGM parameter. This parameter specifes the application program that initially opened the file using the Declare File using CLF (OPEN) or the Open File using CLF (OPNFCLF) command.
All CLF commands that reference the same FILEID and OPNPGM combination share the same view of the file. If one program causes the position within the file to change all programs see that change. If one program closes the file then the file is closed to all programs.
The combination of FILEID and OPNPGM must be unique within the activation group the application program is running in.
If the program name is *CURPGM then the library qualifier for this parameter is ignored. The library of the current program will be used.
Single values: Program opening file
- *CURPGM
- The current program opened the file associated with FILEID. It is this file open instance that is to be used.
Qualifier 1: Program opening file
- name
- Specify the name of the program that initially opened the file identified by FILEID. It is this file open instance that is to be used.
Qualifier 2: Library
- *CURLIB
- The current library for the thread is used. If there is no current library for the thread then library QGPL is used.
- name
- Specify the name of the library where the program that initially opened the file is located.
Examples for CHAIN
Example 1: Reading an Employee Record by Key
Pgm
/******************************************************/
/* Declare the Employee master file VC2EMP and CLF */
/* related indicators */
/******************************************************/
File FileID(VC2EMP)
Inds CLFInd(*Yes)
/******************************************************/
/* Open the file using keys */
/******************************************************/
Open VC2EMP AccMth(*Key)
/******************************************************/
/* Randomly read the employee record where the */
/* employee number is 205 */
/******************************************************/
Chain 205 VC2EMP RcdNotFnd(&RNF)
/******************************************************/
/* Send the first name of the employee or a message */
/* if the record was not found */
/******************************************************/
If Cond(*Not &RNF) Then( +
SndPgmMsg Msg(&EmpFName))
Else Cmd(SndPgmMsg Msg('Record not found'))
/******************************************************/
/* Close the file and return */
/******************************************************/
Close VC2EMP
EndPgm
The source for the example program can be found in member RPG_RDKEY of source file VC2CLSRC in library VC2CLF. The source for physical file VC2EMP can be found in member VC2EMP of source file QDDSSRC in library VC2CLF.
The VC2EMP physical file should currently exist in library VC2CLF. To compile example RPG_RDKEY into QTEMP you can use the commands
AddLibLE Lib(VC2CLF)
CrtBndCLF Pgm(QTEMP/RPG_RDKEY) SrcFile(VC2CLSRC)
Example 2: Reading an Employee Record by RRN
/******************************************************/
/* This program randomly reads the 12th record of the */
/* VC2EMP physical file by relative record number. */
/* The employee name found (Ruth) is displayed. The */
/* record is then deleted and an attempt to read the */
/* same record made. The record should not be found */
/* as it has been deleted and a message is sent based */
/* on whether or not the record is successfully read. */
/* The program then writes a new 12th record to add */
/* a new employee. The program then re-reads the 12th */
/* record and displays the employee name found (Chad) */
/******************************************************/
Pgm
/******************************************************/
/* Declare the file and CLF indicators */
/******************************************************/
File FileID(VC2EMP)
Inds CLFInd(*Yes)
/******************************************************/
/* Open the file for RRN access and update */
/******************************************************/
Open VC2EMP Usage(*Both)
/******************************************************/
/* Read the 12th record and display the name found */
/******************************************************/
Chain RRN(12) FileID(VC2EMP)
SndPgmMsg Msg(&EmpFName *BCat 'found')
/******************************************************/
/* Delete the record read and try to re-read it. */
/* A record-not-found condition should be returned. */
/******************************************************/
Delete FileID(VC2EMP)
Chain RRN(12) FileID(VC2EMP) RcdNotFnd(&RNF)
If Cond(&RNF) Then( +
SndPgmMsg Msg('Record not found'))
Else Cmd(SndPgmMsg Msg( +
&EmpFName *BCat 'found after delete'))
/******************************************************/
/* Write a new record at the deleted position (RRN 12)*/
/******************************************************/
ChgVar Var(&EmpFName) Value('Chad')
ChgVar Var(&EmpSts) Value(F)
Write RRN(12) FileID(VC2EMP)
/******************************************************/
/* Read the 12th record and display the name found */
/******************************************************/
Chain RRN(12) FileID(VC2EMP)
SndPgmMsg Msg(&EmpFName *BCat 'found after write')
/******************************************************/
/* Close the file and return */
/******************************************************/
Close VC2EMP
EndPgm
The source for this example can be found in member RPG_RRNUSG of source file VC2CLSRC in library VC2CLF. The source for file VC2EMP can be found in member VC2EMP of source file QDDSSRC in library VC2CLF.
The VC2EMP file should currently exist in library VC2CLF. To compile RPG_RRNUSG into library QTEMP you can use the commands
AddLibLE Lib(VC2CLF)
CrtBNDCLF Pgm(QTEMP/RPG_RRNUSG) SrcFile(VC2CLSRC)
Prior to running RPG_RRNUSG you should reload the VC2EMP database file to ensure that the expected results are seen. To reload the file you can refer to the source member DEV_LOAD in source file VC2CLF/VC2CLSRC or Appendix D of the CLF Programmer's Guide.
After reloading the VC2EMP file you can call RPG_RRNUSG with the command
Call Pgm(QTEMP/RPG_RRNUSG)
You should see the following messages displayed
Ruth found
Record not found
Chad found after write
Error messages for CHAIN
*ESCAPE Messages
- CPF0001
- Error found on &1 command.
- VC2501A
- File &1 is not open for access by relative record number.
- VC2501B
- Record not found in file &1.
- VC2501C
- End of file for file &1.
- VC25021
- The &4 command was not successful when accessing File ID &2.
- VC25025
- Target datatype of &1 not recognized.
- VC2502E
- File ID &1 is not open.
- VC25065
- RCDBUF parameter is missing on &2 command.
- VC25076
- Record in file &1 is locked by another job.
- VC29002
- Function did not complete. See previously listed messages related to possible user errors.
- VC29003
- Function did not complete. See previously listed messages for possible cause.
- VC29004
- Function did not complete. See previously listed messages for possible cause.
- VC29005
- Function did not complete. Contact your service provider.
- VC29013
- Function did not complete. See previously listed messages for possible cause.
|