IBM i e-Book
A Developer’s Guide to Mastering IBM i Concepts
IBM i Index
Report Program Generator (RPG)
File Handling
Types of files:
Multiple types of file exist in an IBM i series native filesystem that we can use in RPGLE programs/modules.
- Database files:
- It includes file that can contain data in tabular form.
- Physical and logical files are database files.
- In case of database file, the file type on F-Spec can be.
- I for using file in Input mode for reading records.
- O for using file in output mode for writing records to the file
- U for opening file in update mode for updating existing records.
- We can also use, file addition with input and update mode to add records to the file.
- In free-format, we use usage keyword to designate the mode in which it will be used in the program. The possible values are.
- *Input for using file in Input mode for reading records.
- *Output for using file in output mode for writing records to the file
- *Update for opening file in update mode for updating existing records.
- *Delete for deleting the records from the file.
- You can use *input with *output, to read and write records without update. It is same as file addition that we use in fixed format.
Below are some examples.
Fixed format
FPRODUCTS IF E DISK
Free format
dcl-f PRODUCTS usage(*input);
Fixed format
FPRODUCTS IF A E DISK
Free format
dcl-f PRODUCTS usage(*input:*output);
Fixed format
FPRODUCTS UF E DISK
Free format
dcl-f PRODUCTS usage(*delete);
- Workstation Files
- A WORKSTN file is an externally described display-device file that is used to display information and takes user input.
- The most used externally described WORKSTN file is a display file.
- The file type on F-Spec for WORKSTN file is C, means combined.
Below is an example.
Fixed format
FORDERDSPF CF E WORKSTN indds(IndDs) F sfile(SFLORD:S1RRN)
Free format
dcl-f ORDERDSPF workstn indds(IndDs) sfile(SFLORD:S1RRN) ;
- Printer files
- A printer file is a virtual file having data specifications used for later output to a printer.
- A printer file can only be used as output type and O needs to be specified in the F-Spec
Below is an example.
Fixed format
FREPORTDN O E PRINTER
Free format
dcl-f REPORTDN printer;
Multi-member Physical files:
A physical file can have multiple members. By default, when a PF is created it has only one member by the same name as the file. We can use the ADDPFM command to add a new member to the PF.
Below are a few useful keywords that help us in dealing with multi-member files easier.
- EXTMBR: This RPGLE keyword is used on an F-spec and describes which member of the file will be opened at program initialization. You can specify a member name, or ‘*ALL’, or ‘*FIRST'(default). The member-name should be in upper case. We can also use variable names for the member names but one of the below considerations should be kept in mind for the variable declaration.
- Use the INZ keyword to initialize the member-name on the D specification.
- Passing the value in as an entry parameter
- Using a program-global variable that is set by another module.
- Below is an example of the keyword with *ALL.
Fixed formatFPRODUCTS IF E DISK EXTMBR('*ALL')
Free format
dcl-f PRODUCTS usage(*input) extmbr(*ALL');
In the above example, all the members are read sequentially. In other words, when all the records from the first member have been read, the program will start reading then the records in the second member.
- Consider another example of a file FRUITS having multiple members. For each member we will have to read the file and do some processing. So, we can use the keyword with member-name as a literal.
Fixed formatFPRODUCTS IF E DISK EXTMBR('MANGO’)
Free format
dcl-f PRODUCTS usage(*input) extmbr(‘MANGO’);
- Sometimes, we have a use case where the member-name is not constant and is changed based upon some conditions. In that case, we can use a variable for the member-name.
Fixed formatFPRODUCTS IF E DISK EXTMBR(MBRNAME)
Free format
dcl-f PRODUCTS usage(*input) extmbr(MBRNAME);
As the file will be opened at program initialization, the MBRNAME must be populated in upper-case before that. You can declare the variable and initialise it with a default value or the variable can be received as an *entry parameter.
- There is another use-case where we have a dynamic member name, let’s suppose with today’s date. E.g OR20240101 is the member-name for a multi-member order file having members for each date.
To read the member as per today’s date, we can use below logic. We use the USROPN keyword and initialize the variable later in our program, but, before doing an open on the file.
dcl-f PRODUCTS usage(*input) extmbr(MBRNAME) usropn; dcl-s MBRNAME char(10); MBRNAME = ‘OR’ + %char(%Date():*iso0); Open PRODUCTS; Setll *loval PRODUCTS; Read PRODUCTS; Dow not %eof(PRODUCTS); Validate(); Read PRODUCTS; Enddo; Close PRODUCTS; *inlr = *on;
- EXTFILE: This F-spec keyword is used to specify the file and library which will be opened at program initialization. Below are the possible values for the keyword. The values must be in upper-case.
- filename
- libname/filename
- *LIBL/filename
- *EXTDESC
Fixed format
Finput if f 10 disk extfile(‘MYLIB/IN2024’)
Free format
dcl-f input usage(*input) extfile(‘MYLIB/IN2024’);
If a variable name is used, it must be set before the file is opened. For files that are opened automatically during the initialization part of the cycle, the same considerations apply as EXTMBR.
The example above shows how you can call the file any name you would like, in this case, it is input. The EXTFILE tells the program where to find the file, the library name is optional. In this case, the file is in MYLIB. This could be considered a replacement for the CL command OVRDBF.
- EXTNAME: This F-Spec keyword is used with data structure declaration to fetch the field descriptions of the file specified. Below are the examples:
Fixed formatD recOrd E DS extname(‘ORDHDR’)
Free format
dcl-ds record extname(‘ORDHDR’);
File read Op-Codes:
- SETLL: SETLL sets the file pointer at the lower limit of the record entry where the key field/RRN value is greater than or equal to the factor-1 search argument value. After positioning the file pointer, we can go for any file operation e.g. READ, READP,READPE, READE which are discussed further down the line.
- In factor-1 we can use figurative constant *LOVAL, *HIVAL, *START, *END or we can use RRN VALUE, KEY VALUE, KEY LIST or KEY DS.
- To determine if the record having the key field/RRN value exactly same as the search argument value in factor-1 is found, we can use %EQUAL BIF.
Fixed format
C 'MONKEY' SETLL RECORD
Free format
Setll ‘MONKEY’ RECORD;
- SETGT: SETGT sets the file pointer at the higher limit of the record entry where the key field/RRN value is greater than the factor-1 search argument value. After positioning the file pointer, we can go for any file operation e.g. READ, READP,READPE, READE which are discussed further down the line.
- In factor-1 we can use figurative constant *LOVAL, *HIVAL, *START, *END or we can use RRN VALUE, KEY VALUE, KEY LIST or KEY DS.
- To determine if the record having the key field/RRN value exactly same as the search argument value in factor-1 is found, we can use %EQUAL BIF.
Fixed format
C 'MONKEY' SETGT RECORD
Free format
Setgt ‘MONKEY’ RECORD;
- READ: This opcode is used to read the records from a database file. The record is read based on the pointer set by SETXX opcodes, once the record is read it moves the pointer to next available record. This generally is used with *LOVAL/*HIVAL and SETXX opcodes. E.g. SETLL sets the file pointer at the first occurrence of the record where the key field/RRN value is greater than or equal to the factor-1 search argument value. After positioning the file pointer, we can go for any file operation like READ.
- We can also use a data structure as a resultant field to retrieve the values in it.
- If a file is declared in update mode, the read opcode takes an exclusive lock on the record which can cause issues if multiple programs are using the file at the same time. To circumvent this, we can use READ opcode with (n) extender, to read the file with no lock.
To monitor read opcode for error we can also use the (e) extender and check for errors on the next line using %error() built-in function.
Fixed format syntax:
Resulting Indicators Factor 1 Opcode Factor 2 Result Field HI LO EQ READ(N|E) File or record format name Data structure to hold the result Error End-of-file condition indicator Free format Syntax:
Read(n|e) file/record format [Data Structure]
- READE: This opcode is used to read an exact match of the key specified in the factor 1. If multiple records for an exact criterion are to be read, READE can be used with SETXX opcodes with factor 1.
- If the matching criteria is not found the EOF condition is reached.
- To handle exceptions, operation extender (e) can be used.
- READP: It is generally used to read the file in reverse order. READP moves the pointer to the previous record and reads the record and again moves the pointer to next previous position. If there are no more records it sets EOF indicator to *ON. It is usually used with SETLL and *HIVAL.
0001.00 FORDERS IF E K DISK 240105 0002.00 C *HIVAL SETLL ORDERS 240105 0003.00 C READP ORDERS 240105 0004.00 C DOW NOT %EOF() 240105 0005.00 C PNUM DSPLY 240105 0006.00 C READP ORDERS 240105 0007.00 C ENDDO 240105 0008.00 C SETON LR 240105
- READPE: This opcode is used to read an exact match of the key specified in the factor 1. If multiple records for an exact criterion are to be read, READPE can be used with SETXX opcodes with factor 1. Once a record is read it moves the pointer to next previous matching record for the key specified in factor 1.
- If the matching criteria is not found the EOF condition is reached.
- To handle exceptions, operation extender (e) can be used.
- READC: This opcode is used with subfiles, and it helps in identifying which subfile records have been modified. Exceptions can be handled by operation extender (e) and EOF indicator is set once the EOF condition is met. See below example where READC is being used to read changed record from subfile SFLORD.
0008.01 C READC SFLORD 0008.02 C DOW NOT %EOF 0008.03 C SELECT 0008.04 C ACTION WHENEQ '1' 0008.05 C EXSR HEADER 0008.06 C ACTION WHENEQ '2' 0008.07 C EXSR DETAIL 0008.08 C ACTION WHENEQ '4' 0008.09 C EXSR FOOTER 0008.10 C ACTION WHENEQ '5' 0008.11 C EXSR SUM 0008.12 C OTHER 0008.13 C EXSR VALIDATE 0008.14 C ENDSL 0008.15 C READC SFLORD 0008.16 C ENDDO
- CHAIN: This opcode is used to find an exact match for the value specified in factor 1. Under the covers, it is similar to SETLL and READE. The only difference is CHAIN cannot fetch the second exact match if used in a do-while loop. You can also use RRN number as factor 1 for sequential read if the file does not have any key defined.Operation extenders (n) and (e) can be used to for reading the record with no lock and error handling respectively.
0172.00 C EVAL KEYV = S_PNUM 0173.00 C KEYV CHAIN(E) HDRREC 0174.00 C IF %FOUND() 0175.00 C EVAL ORDBADD = S_ADDR 0176.00 C UPDATE HDRREC 0177.00 C ENDIF
Write Op-Code:
This opcode creates a new record in a database file or can be used with display files to output data on the screen. The opcode supports data structures as well. Below is an example for file ORDER with record format ORDERA.
Without Data structure
WRITE ORDERA;
With Data structure
WRITE ORDERA record;
Update Op-Code:
This opcode updates an existing record in a database. There should be a read operation prior to the update opcode. The opcode supports data structures as well. Below is an example for file ORDER with record format ORDERA.
Without Data structure
Update ORDERA;
With Data structure
Update ORDERA record;
Specific field update
Update ORDERA %fields(fld1:fld2:...);