Read file

From BR Wiki
Revision as of 16:32, 10 August 2018 by Gordon.dye (talk | contribs) (→‎Syntax)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The Read (REA) file statement accesses a record from internal or external files and assigns values to variables.

Comments and examples

An internal or external file must already be opened and assigned a file number before a READ file statement can be used. READ file can be used with files opened as INPUT or OUTIN, but not OUTPUT. In the following example, the file SHOWDOWN is opened as #6:

03940 OPEN #6: "NAME=SHOWDOWN", INTERNAL, INPUT
03950 READ #6,USING 3960: COMPANY$
03960 FORM C 10

Internal files may be accessed SEQUENTIAL, RELATIVE, or KEYED depending on the OPEN statement. Similarly, external files may be opened SEQUENTIAL or RELATIVE. READ, REWRITE and DELETE can access -by record number -a file opened for keyed processing without disturbing the key position in the file. This is much faster than using a key. The following is an example:

00100 OPEN #5: "NAME=data,KFNAME=key", INTERNAL,OUTIN,KEYED
00110 READ #5,USING F5,KEY=K1$: QTY1
00120 LET RRN = REC(5) ! save record number from master file
00130 READ #5,USING F5,KEY=K2$: QTY2
00140 IF QTY2>QTY1 THEN REWRITE #5,USING F5,REC=RRN:QTY2

Syntax

READ #<file number> [, USING {<string expression>|<line ref>}] [, <positional parameter>] [, KEYONLY ] {[, KEY{=|>=} <string expression>]|[, SEARCH ]|[, REC=<numeric expression>]|[, POS=<numeric expression]]>]} [, {RESERVE|RELEASE}] : 
[{Mat <array name>|<variable name>}][,...]  [<error condition> <line ref>][,...]

Parameters

"File-num" is an integer or numeric expression, matching the READ statement with a file of the same number, which must already be identified in an OPEN statement.

The "USING" keyword is part of a clause, which specifies either the "line-ref" of a FORM statement or a "string-expr" containing a FORM statement.

The optional "KEY" and "SEARCH" parameters are used with internal files opened for KEYED processing; after the string expression is evaluated (usually a simple string variable or constant), the system reads the first record which matches the key field. If a KEY or SEARCH clause is not specified, the system inputs the next record in key sequence.

For complete information about the KEY and SEARCH parameters and the "=" and ">=" operators (used for full and partial matches either exactly equal or "next greater"), see more in the Index Facility.

The optional "REC = num-expr" clause is used with internal files opened for RELATIVE or KEYED processing or with external files opened for RELATIVE access. Its purpose is to position to a specified record number before reading. After the numeric expression (usually a simple numeric variable or constant) is evaluated and rounded to an integer, the system reads that record number. If "REC = num-expr" is not specified, the system sequentially reads the next active record.

The optional "POS = num-expr" clause is used only with external files opened for RELATIVE processing; its purpose is to position to a specified byte before reading. After the numeric expression (usually a simple numeric variable or constant) is evaluated and rounded to an integer, the system reads a complete record beginning at the specified byte number. If "POS = num-expr" is not specified, the system sequentially reads the next complete record after the last byte read.

The "RESERVE" and "RELEASE" parameters specify record locking rules for multi-user systems. "RESERVE" instructs the system to hold all previous locks for the file and lock the current record. "RELEASE" releases all previous locks for this file and does not lock the current record.

"Var-name" represents a list of variables to be assigned values. Multiple specifications must be separated by commas. If "var-name" is omitted, the record is still read and may be accessed with the REREAD statement.

READ file provides error processing through the optional "error-cond line-ref" parameter. See Error Conditions for more information.

Positional parameters

These positional parameters can be used with the READ statement:

  • FIRST
  • LAST
  • PRIOR
  • NEXT
  • SAME

Additionally the following are available for System/36 compatibility:

The parameters may be used with Business Rules! internal files which have been opened for either RELATIVE or KEYED access, and with external files. The files must be opened for either INPUT or OUTIN.

If positional parameters are used, DELETE and REWRITE do not need to follow a READ.

In the following sample syntax sentences, "pos-parm" represents the FIRST, LAST, PRIOR, NEXT or SAME keyword:

READ #file-num,USING line-ref,pos-parm: var-name error-cond line-ref
REWRITE #file-num,USING line-ref,pos-parm: var-name error-cond line-ref
DELETE #file-num,pos-parm: error-cond line-ref
RESTORE #file-num,pos-parm: error-cond line-ref

The FIRST keyword resets the file pointer to the first record in the file before execution of the I/O operation. If the file is empty, an EOF error is generated. The LAST keyword positions the file pointer to the last record in the file before execution of the I/O operation. If the file is empty, an EOF error is generated.

The PRIOR, NEXT and SAME positional parameters operate according to the last record referenced in the file. The last referenced record is the one that has most recently been processed by a RESTORE with a parameter (positional, REC= or KEY=), a WRITE to a relative file, a READ, a REREAD, a REWRITE, or a DELETE.

If PRIOR, NEXT or SAME positioning is attempted when no records have been referenced or after a RESTORE with no parameters has been issued, Business Rules will respond as stated below. This status can be tested with the REC function, which will return a zero for the current record when no records have been referenced. The PRIOR keyword positions the file pointer to the record previous to the last referenced record in the file. However, in a situation where a READ PRIOR, DELETE PRIOR or REWRITE PRIOR follows a RESTORE with a parameter, the file pointer is positioned to the same record that is referenced by the RESTORE.

The only exception to this is when S/36-MODE is ON, in the above situation the file pointer will then position to the previous record if one exists or else it will generate an EOF error. If PRIOR is used when no records have been referenced, an EOF error is also generated.

The NEXT keyword positions the file pointer to the record following the last referenced record in the file. If no record has been referenced, the first record in the file is accessed. If the file is empty or the file pointer was already at the last record, an EOF error is generated. If a READ NEXT, DELETE NEXT, or REWRITE NEXT follows a RESTORE with a parameter, the same record is processed.

The SAME keyword positions the file pointer to the last referenced record in the file. If no records have been referenced, error 0715 (Illegal sequence) is generated. Note that the difference between READ SAME and REREAD is that READ SAME actually reads the file again, while REREAD only unpacks the data from the buffer.

The following sample code and output shows an example of positional parameters in use:

0130 OPEN #1: 'name=test.dat,recl=15,replace,kfname=test.key,kps=1,kln=3',INTERNAL,OUTIN,KEYED
00140 FORM C 3,N 3
00150 ! write 7 records with letters A through G as keys
00160 FOR I = 1 TO 7 : WRITE #1,USING 140: CHR$(64+I),I : NEXT I
00170 !
00180 PRINT "KEYED:" : GOSUB TESTREAD ! read keyed
00190 CLOSE #1:
00200 OPEN #1: 'name=test.dat',INTERNAL,INPUT,RELATIVE
00210 PRINT : PRINT "RELATIVELY:" : GOSUB TESTREAD ! read relative using same logic
00220 END
00230 TESTREAD: !
00240 READ #1,USING 140,FIRST: A$ : PRINT "FIRST ";A$
00250 READ #1,USING 140,SAME: A$ : PRINT "SAME ";A$
00260 READ #1,USING 140,LAST: A$ : PRINT "LAST ";A$
00270 READ #1,USING 140,PRIOR: A$ : PRINT "PRIOR ";A$
00280 READ #1,USING 140,NEXT: A$ : PRINT "NEXT ";A$
00290 PRINT "DESCENDING KEY: "; ! read whole file by descending key
00300 RESTORE #1,LAST: : FOR I=1 TO 7 : READ #1,USING 140,PRIOR:A$ : PRINT A$; : NEXT I : PRINT
00310 RETURN

Output:

KEYED
FIRST       A
SAME        A
LAST        G
PRIOR       F
NEXT        G

DESCENDING KEY: G F E D C B A

RELATIVELY
FIRST       A
SAME        A
LAST        G
PRIOR       F
NEXT        G

DESCENDING KEY: G F E D C B A

For disambiguation, see Pos Parameter


KEYONLY

The READ statement's KEYONLY parameter allows you to read both the key and the record number in a keyed file without reading the corresponding record in the master file. This feature was implemented to return the key if the master file record is locked and is being read by key. It can also be used to obtain keys sequentially, without the overhead of reading the master file.

The KEYONLY parameter is valid only for files opened INPUT KEYED or OUTIN KEYED. It may be used with positional parameters to specify the key that is to be read. If no positional parameter is specified, the next key will be read. FORM statements corresponding to the key length and B 4 for the record number should be used. If the record length of the master file is not at least four bytes more than the key length, the record number is not returned.

Read file KEYONLY without having read a master record to allocate a buffer caused the task to hang. BR has always required a master record to be read before accessing a file KEYONLY. Now this error condition produces BR error 0718.

While Business Rules! reads only the key file when the KEYONLY parameter is used, it does move the file pointer in the master file to the position of the record just read.

Note that it is very important to keep the key file updated if this feature is to be used. Otherwise, READ with the KEYONLY parameter could return an incorrect record in a situation where a master file record is deleted or rewritten after a READ with a REC= parameter.

A REREAD, DELETE, or REWRITE following a READ with the KEYONLY parameter will return an error.

LINK=string

The READ file statement accepts the LINK=string parameter. It can be used only on LINKED files that have been opened using the KPS= and KLN= parameters. When READ with LINK= is executed, Business Rules will compare the data in the key area specified by the OPEN statement to the LINK= string. If they do not match, error code 4282 will result.

Error 0718 (Key length conflict) will result if you specify LINK= in a READ statement but the linked file has not been opened using the KPS= and KLN= parameters.

The practical way to access records in a linked list is to position the file pointer to the anchor point of the desired linked list with a RESTORE REC= (the REC= number should be stored in the master file and updated whenever the list is accessed). From this position, the program should perform sequential READs until the desired record is found. Note that any attempt to read beyond the last record in the list will result in an error 4270 (End of file). The same error will occur on any attempt to READ PRIOR from the anchor record of a list.


Defaults

1.) Unformatted.
2.) Read the next record.
3.) Lock current record after releasing all previously locked records.
4.) Read the record but do not assign values.
5.) Interrupt the program if an error occurs and "ON error" is not active.

Technical Considerations

1.) Relevant error conditions are: CONV, EOF, ERROR, EXIT, IOERR, LOCKED, NOKEY, NOREC, and SOFLOW.
2.) If a string-expr is used with a USING clause, it must begin with "FORM ". This technique executes relatively slowly because the string is compiled on each execution of the READ statement.
3.) Omitting the USING clause allows unformatted file processing. See File I/O for more information.
4.) If a record has been deactivated by a DELETE statement in an internal file, a sequential READ skips over the deleted record and reads the next available record which has not been deleted (or EOF occurs); the deleted records do not produce an error when reading is sequential.
5.) In RELATIVE and KEYED processing of internal or external files, READ with and without the REC= clause can be intermixed. Without the REC= clause, READ sequentially inputs the next record in record or key order.
6.) In RELATIVE processing of external files, READ with and without the POS= clause can be intermixed. Without the POS= clause, READ sequentially inputs the next complete record from the current position of the file pointer (just after the last byte of the last record read).
7.) In RELATIVE processing of external files, READ with the POS= clause and the REC= clause can be intermixed; however, this is not encouraged.
8.) In KEYED processing of internal files, READ with and without the KEY= clause can be intermixed. Without the KEY= clause, READ inputs the next record in KEY sequence. If no KEYED I/O operations have been performed, the pointer is initially positioned at the start of the index file.
9.) If the file is opened for KEYED processing, but READ statements do not specify a KEY or SEARCH clause, the file is read in ascending order by key field. This technique is sometimes called read-sequential-by-key.
10.) If duplicate keys are allowed, both types of READ (with and without KEY= clauses) should be used to exhaust all possible records with the duplicate key. READ with a KEY= or SEARCH= clause will always return the first record with the matching key; a duplicate key, if it exists, would appear sequentially after this key.
11.) The NOKEY error condition traps errors that occur when there is no match for the specified key. Such an error will occur if the record has been deleted, if it was never written, or if it was written without this index file being open.
12.) When OPTION INVP is in effect, the normal input of commas and periods is interchanged in PIC, N, NZ, G and GZ format specifications to produce European-style numbers. See the OPTION statement for details.
13.) An untrapped error is an error which occurs but is not addressed by a coded error condition (either in an ON statement or at the end of a program line). Business Rules proccesses certain untrapped errors specifically in READ file statements in the following situations:
  • After a READ statement has successfully filled the input buffer, and
  • During the process of converting data according to a specified FORM statement.

When the situation fits these requirements, the following will apply:

  1. The computer will beep and wait for operator response.
  2. A READ statement which encounters an untrapped conversion error is deemed unsuccessful and the system acts as if the READ had not been attempted except that the value of CNT is set and variables processed prior to the error are assigned new values.
  3. Subsequent REREAD statements are not allowed because the READ statement was not successful. Similarly, subsequent DELETE statements are not allowed unless a KEY= or REC= clause is used, and subsequent REWRITE statements are not allowed unless a KEY=, REC= or POS= clause is used.
  4. The record is not locked.
  5. The next sequential READ statement will read this same record again.
  6. The file pointer is positioned wherever it was before the error-causing READ statement.
  7. The REC(n) function will not return the record number of the bad record (instead, it returns the number of the last successfully processed record, however far back that may be).

The types of errors which will enact this special processing include conversion (CONV) errors, string overflow (SOFLOW) errors, trying to read past end of record (0714), and illegal format specification in FORM statement (0816) errors.

14.) Business Rules! processing for trapped errors on a READ file statement are as follows:
  • A READ statement which encounters a trapped conversion error is deemed successful.
  • Subsequent REREAD, DELETE or REWRITE statements are allowed on the record just read.
  • The record is locked if record locking was requested (either explicitly or by default).
  • The next READ statement reads the next record.
  • The REC(n) function returns the record number of the bad record (which is considered the last record successfully processed in the trapped case).
15.) When a short record is encountered while reading EXTERNAL files, error 4271 is produced as before. But now the data that was read is available in the buffer to be accessed with a REREAD. CNT tells how many bytes were actually read. The remainder of the input buffer is set to binary zero. Subsequent read attempts now yield an EOF error (4270) instead of additional 4271 errors.