Document revision date: 30 March 2001
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

Guide to OpenVMS File Applications


Previous Contents Index

8.2.3 Updating Records

The Update service modifies an existing record in a file. Your program must first locate the appropriate record and optionally retrieve the record itself, by calling either the Find service or the Get service. As with the Put service, your program must provide a buffer within the data portion of the program to hold the record that is to be updated.

When calling RMS directly, the program must also supply the length of each record to be written. This is a constant value when updating fixed-length records but varies from record to record when updating variable-length records or VFC records. Note that some high-level language compilers may automatically handle record buffer allocation and size specification or may supply a means to simplify its specification.

Your program must establish the current-record position before it updates a record. If the file is shared, the service that establishes the record position should also lock the record.

When you update indexed file records, take care not to alter the value of any key field that has been specified as unchangeable, for example, the primary key. To change the value of a record's primary key, you must replace the existing record with a new record having the desired primary key value. You can do this using the Put and Delete services respectively, or, where applicable, you may use the Put service with the update-if (RAB$L_ROP RAB$V_UIF) option.

When updating indexed file records, you do not have to specify the key of reference.

For more information about the Update service and record-processing options, refer to the OpenVMS Record Management Services Reference Manual.

8.2.4 Deleting Records

The Delete service removes a record from the file. You cannot delete individual records from sequential files, but you can truncate sequential files using the Truncate service. As with the Update service, the Delete service must be preceded by a Find or Get service to establish the current-record position.

When deleting records from an indexed file with alternate indexes, you can specify the fast-delete option to reduce the amount of time needed to delete a record. When you invoke the Delete service and specify the fast-delete option, RMS does not attempt to remove any of the pointers from alternative indexes to the deleted record.

You improve performance by postponing the processing needed to eliminate the pointers from alternative indexes to the record. However, there are disadvantages to using the fast-delete option:

Use the fast-delete option only if the immediate improvement in performance is worth the added space and overhead. Typically, you use the fast-delete option for indexed files that implement alternate keys and require frequent maintenance.

Conversely, avoid the fast-delete option for most read-only indexed files and for indexed files that are infrequently updated.

For more information about the Delete service, refer to the OpenVMS Record Management Services Reference Manual.

8.3 Secondary Services

This section provides very brief descriptions of the secondary services. Note that each of the services performs a specialized function with few options.
Connect Allows you to connect to a single record stream or to multiple record streams.
Disconnect Allows you to disconnect a record stream. This is done implicitly when a file is closed, but when using multiple record streams, you may want to disconnect one record stream but not others.
Flush Writes modified I/O buffers and file attribute information maintained in memory to the file.
Free Releases all record locks established by the current record stream.
Next Volume Continues the next volume of a magnetic tape volume set. This service applies only to sequential files.
Release Releases the record lock on the current record.
Rewind Positions the record stream context to the first record of the file.
Truncate Truncates a file beginning with the current record, effectively deleting it and all remaining records. This service applies only to sequential files.
Wait Awaits the completion of an asynchronous record operation (or Connect service).

In addition to the record-processing services, a variety of file-processing services are also available. For more information about both types of processing services and the options that apply to each, see the OpenVMS Record Management Services Reference Manual.

8.4 Record Access for the Various File Organizations

To retrieve or insert a file record for a particular record stream, your program must specify either sequential or random access.

Sequential access can be used with all file organizations. For sequential files, sequential access implies that records are accessed according to their physical position in the file. For relative files, sequential access implies that records are accessed according to the ascending order of relative record numbers. In indexed files, sequential access implies that records are accessed according to a specified ordering of values for a particular key or keys.

Random access is defined as one of the following:

Record access is specified using language statements or by establishing the appropriate control block field values (not offset values) in the RAB.

Note

No FDL attributes are provided for specifying record access.

The appropriate RAB values in the access mode specification field, identified by the symbolic offset RAB$B_RAC, are as follows:

Your program may also need to specify the key or other record identifier needed to access the records. For indexed files, there are additional key-related options.

The record access mode can be changed without reopening the file or reconnecting the record stream. For example, you can use random access by key to establish the current-record position in an indexed file and then retrieve records sequentially by a specified sort order. Note, however, that changing modes in this manner requires program access to the RAB$B_RAC control block field at run time.

The record access mode, in conjunction with the file organization, is what determines the manner in which a record is selected. In the following sections, the sequential and random access modes are discussed in the context of the applicable file organizations. Random access by RFA is discussed separately because it applies to disk files, regardless of file organization.

The following discussion of record access modes is directed primarily toward services that insert records and services that retrieve records. For additional details about these services, see the OpenVMS Record Management Services Reference Manual.

8.4.1 Processing Sequential Files

A program can read sequential files on both tape and disk devices using the sequential record access mode. If the file resides on disk, the random access by RFA mode can be used to read records, and if the file uses the fixed-length record format, the random access by relative record number mode is permitted.

You can add records only to the end of a sequential file.

All record access modes permit you to establish a new current-record position in a sequential file using the Find service. With sequential access, the Find service permits you to skip over records. With either random access by relative record number or random access by RFA, the Find service establishes a starting point for sequential Get services.

You cannot randomly delete records from a sequential file. However, you can randomly update records in a sequential file if the file is on disk and if the update does not change the record size.

The following sections discuss the use of sequential and random access modes with sequential files.

8.4.1.1 Sequential Access

The sequential access mode is supported for sequential files on all devices. It is the only record access mode that is supported for nondisk devices, such as terminals, mailboxes, and magnetic tapes.

With sequential access, RMS returns records from sequential files in the order in which they were stored. When a program has retrieved all of the records from a sequential file, any further attempt to sequentially access records in the file causes RMS to return an end-of-file (no more data) condition code.

In sequential access mode, you can add records only to the end of a sequential file, that is, the file location immediately following the current-record position.

8.4.1.2 Random Access

You can use the relative record number to randomly retrieve and insert records in sequential files having fixed-length records. Records are numbered in ascending order, starting with number 1.

In a sequential file, records are usually inserted at the end of the file. To insert records randomly within the current boundaries of the file at a relative record number less than or equal to the highest record number, set the update-if option (FDL attribute CONNECT UPDATE_IF; RAB$L_ROP bit RAB$V_UIF) to overwrite existing records.

When accessing a sequential file randomly by relative record number, your program must provide the record number at symbolic offset RAB$L_KBF and must specify a key length of 4 at symbolic offset RAB$B_KSZ, in the RAB.

8.4.2 Processing Relative Files

The relative file organization permits greater program flexibility in performing record operations than the sequential organization. A program can read existing records from the file using sequential, random access by relative record number mode or random access by RFA mode. You can write new records either sequentially or randomly, as long as the intended record location (cell) does not already contain a record. You can also delete records.

All record access modes for relative files allow you to establish the current-record position using the Find or Get service. After finding the record, RMS permits you to delete the record from the relative file. After the record is deleted, the empty cell becomes available for a new record. In addition, your program can update records anywhere in the file. For variable-length records, the Update service can modify the record length up to the maximum size specified when the file was created.

When you insert a record into a relative file, the record is placed in a fixed cell within the file. A cell within a relative file can contain a record, can be vacant (never have contained a record), or can contain a deleted record.

The following sections discuss the sequential and random access modes for relative files.

8.4.2.1 Sequential Access

For relative files, the sequential access mode can be used to retrieve successive records in ascending record number. Vacant cells and cells that contain deleted records are skipped over automatically.

8.4.2.2 Random Access

You can directly read a record within a relative file by specifying the appropriate relative record number. If you attempt to read from a nonexistent cell---that is, a vacant cell or a cell containing a deleted record---RMS returns an error message.

To position the record stream at a particular cell, regardless of whether or not it contains a record, use the nonexistent-record option (FDL attribute CONNECT NONEXISTENT_RECORD), or set the RAB$V_NXR bit in the RAB$L_ROP field.

You can use the forward search key options (equal-or-next-key and next-key) to directly access records in relative files, but the reverse search key options are not supported for relative files.

The equal-or-next-key option (FDL attribute CONNECT KEY_GREATER_EQUAL) directs RMS to return a record having a record number equal to or greater than the specified record number. For example, when you specify record number 48, RMS returns record number 48. If RMS does not find record number 48, it returns the first record it encounters having a number greater than 48.

The next-key option (FDL attribute CONNECT KEY_GREATER_THAN) directs RMS to return the record that has the next greater record number. For example, when you specify record number 48, RMS returns record number 49, if record 49 exists.

You can also use random access mode to insert records into relative files. You can even overwrite cells that contain records by selecting the update-if option (FDL attribute CONNECT UPDATE_IF) or by directly setting the RAB$V_UIF bit in the RAB$L_ROP field.

To access a relative file randomly by record number, your program must contain the relative record number in the RAB at symbolic offset RAB$L_KBF and the key length value 4 at symbolic offset RAB$B_KSZ.

8.4.3 Processing Indexed Files

Indexed files provide the most record-processing flexibility. Your program can read existing records from the file in sequential, random access by RFA mode or random access by key mode. RMS also allows you to write any number of new records into an indexed file if you do not violate a specified key constraint, such as not allowing duplicate key values.

In random access by key mode, RMS provides two forward search key options for use with one of four match options (see Section 8.4.3.2). A reverse search key option permits reverse random access when used in combination with either of the two forward search key options.

The search key options are:

Table 8-2 lists the search key types for each option combination. Note that three of the listed combinations are not supported (not allowed) and result in the return of an error message.

Table 8-2 Search Key Types
  Search Key Option Settings
Search Key Type Reverse Equal or Next Next
Equal 1 Off Off Off
Equal or greater than Off On Off
Greater than Off Off On
Not allowed Off On On
Not allowed On Off Off
Equal or less than 2 On On Off
Less than (previous) On Off On
Not allowed On On On


1Default forward search key
2Default reverse search key

If you use the reverse search key option with a set of records that has duplicate keys, only the first record in the set is returned. An application that needs to access all records having duplicate key values requires additional compiler or program logic.

On-disk data structures are designed to provide optimum performance for forward searches. Reverse search performance may be diminished, especially for applications that process long chains of deleted records. To take advantage of built-in caching that improves performance when retrieving successive previous records, specify full key sizes and select the next-key option.

The following C program demonstrates the use of the search key option. The program reads the last and the next-to-last records in a file.


/* 
   REVERSE-SEARCH 
 
 The file is defined by the logical INFILE, and has record and 
 key sizes defined below. 
*/ 
 
#include <rms>  /* defines rabs and fabs */ 
#include <stdio>  /* defines printf  */ 
#include <string> /* defines strlen  */ 
#include <stdlib> /* defines exit   */ 
#include <starlet>  /* defines sys$open, et al  */ 
 
#define RECORD_SIZE 80 
#define KEY_SIZE 10 
 
char INPUT_NAME[] = "INFILE"; 
 
struct FAB infab; 
struct RAB inrab; 
 
error_exit (code, value) 
long code; 
long value; 
{ 
 void lib$signal(); 
 lib$signal (code, value); 
 exit (0); 
} 
 
main () 
{ 
 char record [RECORD_SIZE + 1]; /* record buffer */ 
 char key [KEY_SIZE + 1];  /* key buffer */ 
 long status; 
 
 /* Set up input fab */ 
 infab = cc$rms_fab; 
 infab.fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_UPD | FAB$M_DEL; 
 infab.fab$b_shr = FAB$M_SHRGET | FAB$M_SHRPUT | FAB$M_SHRUPD 
     | FAB$M_SHRDEL; /* read/write sharing */ 
 infab.fab$l_fna = INPUT_NAME; /* logical name INFILE */ 
 infab.fab$b_fns = sizeof INPUT_NAME - 1; 
 
 /* Set up input rab */ 
 inrab = cc$rms_rab; 
 inrab.rab$l_fab = &infab; 
 inrab.rab$b_rac = RAB$C_KEY;  /* key access */ 
 inrab.rab$l_rop = RAB$M_REV | RAB$M_NXT; 
      /* reverse-search, next */ 
 inrab.rab$b_krf = 0;   /* access by primary key */ 
 inrab.rab$l_ubf = record;  /* record buffer */ 
 inrab.rab$w_usz = RECORD_SIZE;  /* maximum record size */ 
 
 /* Open and connect */ 
 status = sys$open (&infab); 
 if (! (status & 1)) 
  error_exit (status, infab.fab$l_stv); 
 status = sys$connect (&inrab); 
 if (! (status & 1)) 
  error_exit (status, inrab.rab$l_stv); 
 
 /* Set key larger than the largest possible real key */ 
 strcpy (key, "~"); 
 inrab.rab$l_kbf = key;   /* key buffer */ 
 inrab.rab$b_ksz = 1;   /* set key length */ 
 
 /* Get and display the last record */ 
 status = sys$get (&inrab); 
 if (! (status & 1)) 
  error_exit (status, inrab.rab$l_stv); 
 record[inrab.rab$w_rsz] = '\0'; 
 printf ("Record: {%s}\n", record); 
 
 /* Set key to the (just-read) largest key */ 
 inrab.rab$l_kbf = record;  /* key buffer */ 
 inrab.rab$b_ksz = KEY_SIZE;  /* set key length */ 
 
 /* Get and display the next-to-last record */ 
 status = sys$get (&inrab); 
 if (! (status & 1)) 
  error_exit (status, inrab.rab$l_stv); 
 record[inrab.rab$w_rsz] = '\0'; 
 printf ("Record: {%s}\n", record); 
 
 /* Close file */ 
 status = sys$close (&infab); 
 if (! (status & 1)) 
  error_exit (status, infab.fab$l_stv); 
} 

You can use the Find service (similar to the Get service), in sequential access mode, random access by RFA mode, or random access by key access mode. When finding records in random access by key access mode, your program can specify any one of the four types of key matches (exact, generic, approximate, generic/approximate) described in Section 2.1.1.2 and Section 8.4.3.2.

In addition to reading, writing, and finding a record, your program can delete or update any record in an indexed file if the operation does not violate specified key characteristics. For example, if the program specifies that key values cannot be changed, any update that attempts to change a key value is rejected.

The next section describes how indexed files are used with the sequential and random access by key modes.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
4506PRO_023.HTML