READ
WTSupported in traditional Synergy on Windows
|
WNSupported in Synergy .NET on Windows
|
USupported on UNIX
|
VSupported on OpenVMS
|
READ(channel, data_area, key_spec[, GETRFA:new_rfa][, KEYNUM:krf_spec] & [, LOCK:lock_spec][, MATCH:match_spec][, NOFILL][, POSITION:pos_spec] & [, RFA:match_rfa][, WAIT:wait_spec]) [[error_list]]
Arguments
channel
The channel on which the file to be read is open. The channel must already have been opened in input, output, append, or update mode. (n)
data_area
A variable that will receive the information. For ISAM files, this argument is used in implied key-of-reference specifications. (a)
key_spec
The ordinal position of the record in the file, the key value to match, or one of the following qualifiers:
Position to the first record in the file before reading. For ISAM files, this is relative to the key of reference.
Position to the last record in the file before reading. For ISAM files, this is relative to the key of reference.
On Windows and UNIX, ^LAST works only on ISAM and relative files. On OpenVMS, ^LAST works only on ISAM files. |
GETRFA
(optional) Returns the record’s RFA. See GETRFA for a complete description.
KEYNUM
(optional) Specifies a key of reference by which to perform the READ. See KEYNUM for a complete description.
LOCK
(optional) Specifies whether the record is to be locked. See LOCK for a complete description.
MATCH
(optional) Defines how a specified key is matched. See MATCH for a complete description.
NOFILL
(optional) Prevents the data area from being padded with blanks when the data returned does not completely fill data_area. See NOFILL for a complete description.
POSITION
(optional) Specifies an absolute position in the file. See POSITION for a complete description.
RFA
(optional) Reads the record with the specified RFA. See RFA for a complete description.
WAIT
(optional) Specifies how long to wait for a record lock to be released. See WAIT for a complete description.
error_list
(optional) An I/O error list. If any one of the specified errors occurs as part of the READ, control is transferred to the associated label.
Discussion
The READ statement retrieves a specified record from a file.
By default, READ locks the record, unlocking any previous automatic lock. If channel is open in update mode and READ tries to access a locked record, a “Record is locked” error ($ERR_LOCKED) is generated. If the program does not trap the error, it is considered fatal.
If the file record size is less than that of the data area, the record is placed into the data area left-justified over blanks. If the file record size is greater than the size of the data area, only the leftmost portion of the record is transferred, and an “Input data size exceeds destination size” error ($ERR_TOOBIG) is generated. (If system option #27 is set, this error is not generated; this option allows a larger buffer to be stored into a smaller destination.)
If you READ the last record in a file opened with block submode, and this record’s length is not a multiple of the file’s buffer size, Synergy DBL generates an “End of file” error ($ERR_EOF) and copies the file record into the buffer. A call to %RSIZE (or %RDLEN) returns the actual length of the record read. Any excess characters in the buffer are not filled.
The record to position to is specified either by the POSITION qualifier, the MATCH qualifier (valid on ISAM files only), the RFA qualifier, or key_spec in the following order of precedence:
1. | If the POSITION qualifier is specified, MATCH, RFA, and key_spec are ignored. |
2. | If the MATCH qualifier is specified, the RFA qualifier is ignored, unless MATCH:RFA is specified. Key_spec is also ignored if MATCH:RFA or MATCH:SEQ are specified. |
3. | If the POSITION qualifier is not specified, but RFA is, key_spec is ignored. |
4. | If the POSITION, MATCH, and RFA qualifiers are not specified, key_spec defines the record to position to. |
See the note under Record locking for information about inconsistencies that may occur after an I/O error is encountered. |
READ with ISAM files
By default, if MATCH is not specified (which is equivalent to setting MATCH:Q_GEQ) and no record’s key field begins exactly as specified by the key value, the next available record according to the collating sequence of the index of reference is located and a “Key not same” error ($ERR_KEYNOT) occurs. The data is still transferred, and the record is still locked. If no higher record exists, an “End of file” error ($ERR_EOF) occurs. (See MATCH for more information about how keys are matched.)
If you specify a numeric key value in key_spec (d or i) and the file’s defined key is also numeric (d, i, or u), the value will be converted to the appropriate type and length to locate the record. Otherwise, if either the key value or defined key is non-numeric (implied or segmented), and you specify a key value in key_spec whose length is greater than the file’s defined key, only the first part of the key value locates the record. If the key value length is less than the size of the file’s defined key, the value is called a partial key. In this case, the record located will be the first one that has a key that begins with the specified value.
The key of reference is determined as follows:
- If the KEYNUM qualifier is specified, it defines the key of reference.
- If KEYNUM is not specified, READ uses the implied key of reference. The implied key of reference is a field within data_area that matches the offset and contiguous length of the key defined by key_spec. If a match is not found, the first key that matches the offset and has a greater length than key_spec is the implied key of reference.
- If KEYNUM is not specified and the conditions for an implied key of reference do not exist, READ uses the primary key as the key of reference if system option #45 is not set.
If you want to READ a segmented key that is specified by key_spec, you must first construct that key by concatenating each segment. You can use the %KEYVAL intrinsic function to return the extracted key value from the specified record. See %KEYVAL for more information.
On OpenVMS, if you specify both the RFA and KEYNUM qualifiers on the READ statement, KEYNUM must specify the primary key as the key of reference (Q_PRIMARY or 0).
READ with non-ISAM files
On Windows and UNIX, if a non-ISAM file is opened with no submode specified and the OPEN does not specify a record size, the runtime assumes the file contains records that are each the same size as the receiving data area. Based on this size and the number of the record to be retrieved, the runtime determines the offset within the file and begins at the first character of the record.
If you attempt to read a record beyond the end of file, you’ll get an “Illegal record number specified” error ($ERR_RECNUM).
See also
Input and output statement qualifiers for a complete description of each I/O statement qualifier
Examples
The following internal subroutine searches for an ISAM record based on the primary key and a sequence number, optionally skipping records marked as purged.
prifind, read(g_datachn, g_modlog, seqnum) & [KEY = notfound, EOF = notfound] if ((.not. g_inc_purg) .and. (status .eq. "P")) begin xcall prompt("Requested record has been purged." & "Enter 'Y' to include purged records", char) if (char .eq. 'Y') ;Toggle incl of purged records begin g_inc_purg = (g_inc_purg .xor. 1) xcall tprgmsg ;Update the status message end while ((.not. g_inc_purg) .and. (status .eq. "P")) reads(g_datachn, g_modlog, notfound) end return notfound, a_err = E_NOTFOUND return
The following example references a data file that contains item information that uses the item number as the reference code. The reference codes are numerically ordered, starting with item number 00001. The example gets an item code number, validates it, and then reads the appropriate record. It calls a user-defined subroutine to display the information, then repeats the whole process.
subroutine get_item a_maxitem ,d a_chn ,d ;Channel opened in i:r mode a_data ,a ;Data area for item record .define TTCHN ,1 record item ,a5 item_num ,d5 proc repeat begin display(TTCHN, "Item #: ") reads(TTCHN, item) [eof=done] item_num = item if (item_num .gt. a_maxitem .or. item_num .le. 0) begin display(TTCHN, "Invalid item number", $scr_mov(-1,-80), $scr_clr(line)) nextloop end read(a_chn, a_data, item_num) xcall show_item(a_data) end done, xreturn endsubroutine