  | 
		
OpenVMS Record Management Services Reference
Manual
 
 
B.3.8 Deleting Records
This service can only be used with relative and indexed files.
Example B-8 illustrates the use of the Delete service.
 
 
  
    | Example B-8 Use of the Delete Service | 
   
  
    
       
      
        .TITLE  DELETE
;
; This program looks up records in the input file and
; deletes those records.
;
        .PSECT  DATA,WRT,NOEXE
INFAB:   $FAB   FNM = <INFILE:>,-       ; Input file logical name
                FAC = <DEL,GET>         ; DEL access
INRAB:   $RAB   FAB = INFAB,-           ; Pointer to FAB
                KBF = INP_STR,-         ; Key buffer
                KRF = 0,-               ; Primary key
                RAC = KEY               ; Keyed access
REC_SIZE = 132                          ; Maximum size records
INP_STR:                                ; Key string/record buffer
        .BLKB   REC_SIZE
INP_STR_D:                              ; Key string descriptor
        .LONG   REC_SIZE
        .LONG   INP_STR
INP_STR_LEN:                            ; Key string length
        .BLKL   1
KEY_PMT_D:                              ; Key value prompt string
        .ASCID  /Please enter key value: /
        .PSECT  CODE,NOWRT,EXE
;
; Initialization - Open file and connect stream
;
        .ENTRY  DELETE,^M<>             ; No registers to save
        $OPEN   FAB=INFAB               ; Open input file
        BLBC    R0,F_ERR                ; Quit on error
        $CONNECT        RAB=INRAB       ; Connect to input
        BLBC    R0,R_ERR                ; Quit on error
;
; Delete record loop
;
READ:
        PUSHAB  INP_STR_LEN             ; Address for string length
        PUSHAB  KEY_PMT_D               ; Prompt string descriptor
        PUSHAB  INP_STR_D               ; String buffer descriptor
        CALLS   #3,G^LIB$GET_INPUT      ; Get input string value
        BLBS    R0,FIND                 ; Quit on error or end-of-file
        CMPL    R0,#RMS$_EOF            ; Was error end-of-file?
        BEQL    DONE                    ; Successful completion
        BRB     EXIT                    ; Error otherwise
FIND:   MOVB    INP_STR_LEN, -          ; Set key size
                INRAB+RAB$B_KSZ
        $FIND   RAB=INRAB               ; Locate the record
        BLBS    R0,DEL                  ; Continue if found
        CMPL    R0,#RMS$_RNF            ; No such record?
        BEQL    READ                    ; Try again
        BRB     R_ERR                   ; Error otherwise
DEL:    $DELETE RAB=INRAB               ; Delete the record
        BLBC    R0,R_ERR                ; Quit on error
        BRB     READ                    ; Go back for more
;
; Close files and exit
;
F_ERR:  PUSHL   FAB$L_STV+INFAB         ; Push STV and STS on
        PUSHL   FAB$L_STS+INFAB         ; stack in reverse order
        CALLS   #2, G^LIB$SIGNAL        ; Signal message
        BRB     EXIT
R_ERR:  PUSHL   RAB$L_STV+INRAB         ; Push STV and STS on
        PUSHL   RAB$L_STS+INRAB         ; stack in reverse order
        CALLS   #2, G^LIB$SIGNAL        ; Signal message
DONE:   $CLOSE  FAB=INFAB               ; Close files
EXIT:   RET                             ; Return with status in R0
        .END    DELETE
 |   
This program uses a key to find and delete a record. To use the $DELETE
macro,
the $FAB macro for the file must set the FAB$V_DEL bit as shown in the
following code example:
 
 
  
    
       
      
INFAB:  $FAB    FNM=<INFILE:>,-
                FAC=<DEL>
 |   
The following program statement invokes the Delete service and points
to the input RAB:
 
 
B.3.9 Updating Records
Example B-9 illustrates the use of the Update service.
 
 
  
    | Example B-9 Use of the Update Service | 
   
  
    
       
      
        .TITLE  UPDATE
;
; This program looks up records in the input file and
; updates those records.
;
        .PSECT  DATA,WRT,NOEXE
INFAB:  $FAB    FNM = <INFILE:>,-       ; Input file logical name
                FAC = <GET,UPD>         ; Read and Write access
INRAB:  $RAB    FAB = INFAB,-           ; Pointer to FAB
                KBF = INP_STR,-         ; Key buffer
                KRF = 0,-               ; Primary key
                RAC = KEY,-             ; Keyed access
                RBF = INP_STR           ; Record buffer
REC_SIZE = 132                          ; Maximum size records
INP_STR:                                ; Key string/record buffer
        .BLKB   REC_SIZE
INP_STR_D:                              ; Key string descriptor
        .LONG   REC_SIZE
        .LONG   INP_STR
INP_STR_LEN:                            ; Key string length
        .BLKL   1
KEY_PMT_D:                              ; Key value prompt string
        .ASCID  /Please input key value: /
DATA_PMT_D:                             ; Data value prompt string
        .ASCID  /Please input new record value: /
        .PSECT  CODE,NOWRT,EXE
;
; Initialization - Open file and connect stream
;
        .ENTRY  UPDATE,^M<>             ; No registers to save
        $OPEN   FAB=INFAB               ; Open input file
        BLBC    R0,FAB_E                ; Quit on error
        $CONNECT        RAB=INRAB       ; Connect to input
        BLBC    R0,RAB_E                ; Quit on error
        BRB     READ                    ; Begin update loop
FAB_E:  BRW     F_ERR                   ; File (FAB) error
RAB_E:  BRW     R_ERR                   ; Record (RAB) error
;
; Update record loop
;
READ:
;
; Prompt for key value to look up.
;
        PUSHAB  INP_STR_LEN             ; Address for string length
        PUSHAB  KEY_PMT_D               ; Prompt string descriptor
        PUSHAB  INP_STR_D               ; String buffer descriptor
        CALLS   #3,G^LIB$GET_INPUT      ; Get input string value
        BLBS    R0,FIND                 ; Quit on error or end-of-file
        CMPL    R0,#RMS$_EOF            ; Was error end-of-file?
        BEQL    ALL_D                   ; Successful completion
        BRW     EXIT                    ; Error otherwise
ALL_D:  BRW     DONE
FIND:   MOVB    INP_STR_LEN, -          ; Set key size
                INRAB+RAB$B_KSZ
        $FIND   RAB=INRAB               ; Locate the record
        BLBS    R0,UPD                  ; Continue if found
        CMPL    R0,#RMS$_RNF            ; No such record?
        BEQL    READ                    ; Try again
        BRB     R_ERR                   ; Error otherwise
;
; Prompt for new data record.
;
UPD:
        PUSHAB  INP_STR_LEN             ; Address for string length
        PUSHAB  DATA_PMT_D              ; Prompt string descriptor
        PUSHAB  INP_STR_D               ; String buffer descriptor
        CALLS   #3,G^LIB$GET_INPUT      ; Get input string value
        BLBC    R0,EXIT                 ; Quit on error
        MOVW    INP_STR_LEN, -          ; Set record size
                INRAB+RAB$W_RSZ
        $UPDATE RAB=INRAB               ; Write the record
        BLBC    R0,R_ERR                ; Quit on error
        BRW     READ                    ; Go back for more
;
; Close files and exit
;
F_ERR:  PUSHL   FAB$L_STV+INFAB         ; Push STV and STS on
        PUSHL   FAB$L_STS+INFAB         ; stack in reverse order
        CALLS   #2, G^LIB$SIGNAL        ; Signal message
        BRB     EXIT
R_ERR:  PUSHL   RAB$L_STV+INRAB         ; Push STV and STS on
        PUSHL   RAB$L_STS+INRAB         ; stack in reverse order
        CALLS   #2, G^LIB$SIGNAL        ; Signal message
DONE:   $CLOSE  FAB=INFAB               ; Close files
EXIT:   RET                             ; Return with status in R0
        .END    UPDATE
 |   
This program uses a key and a new record entered from the terminal to
update a record in the input file.
 
To use the $UPDATE macro, the $FAB macro for the file must specify that
the FAB$V_UPD bit is marked in the file access (FAB$B_FAC) field as
shown in the following code example:
 
 
  
    
       
      
INFAB:  $FAB   FNM=<INFILE:>,-
               FAC=<GET,UPD>
 |   
Before updating a record, the program uses the Find service to locate
the record by executing the $FIND macro located at the FIND label:
 
 
B.3.10 Using Block I/O
In addition to the major types of record access provided by the
sequential, random by key value or relative record number, and random
by RFA access modes, RMS provides another means to access data in a
file: block I/O.
 
Block I/O operations let you directly read or write the blocks of a
file. These operations are provided for users who must keep system
overhead to a minimum and need no interpretation of file data as
logical records, yet still want to take advantage of RMS file
accessibility. Block I/O is an intermediate step between the RMS record
operations and direct use of $QIO system services.
 
The three block I/O services are invoked using the $READ, $SPACE, and
$WRITE macros, respectively.
 
  - The Read service transfers a specified number of bytes to memory.
  
 - The Space service positions a file forward or backward a specified
  number of blocks.
  
 - The Write service writes a specified number of bytes to a file.
  
The Read and Write services always begin on a block boundary.
 
In addition to the Read, Space, and Write services, you can use the
following services on a record stream connected for block I/O
operations:
 
  - The Disconnect service ($DISCONNECT macro)
  
 - The Flush service ($FLUSH macro)
  
 - The Next Volume service ($NXTVOL macro)
  
 - The Rewind service ($REWIND macro)
  
These services perform miscellaneous operations or disconnect the
record stream. They do not work on the contents of the records
themselves.
 
You cannot perform block I/O operations on shared files. That is, file
access
for block I/O operations is denied unless the FAB$V_UPI or the
FAB$V_NIL bit is set in the FAB$B_SHR field.
 
You specify block I/O operations for a record stream by setting the
FAB$V_BIO bit in the file access (FAB$B_FAC) field as input to the Open
or Create services. If you intend to write to the file, you must set
the PUT option in the FAB$B_FAC field; if you intend to read from the
file, you must set the GET option in the FAB$B_FAC field. If you set
the FAB$V_BIO bit when you create a relative or indexed file, RMS omits
prolog processing for indexed files and
initial space prezeroing in relative files.
 
For files of unknown organization, block I/O is the only form of
processing allowed. Processing proceeds identically to that for block
I/O to the relative file organization described previously.
B.3.11 Mixed Block and Record I/O
 
How and when RMS allows you to switch between record I/O and block I/O
depends on the organization of the file being accessed.
 
When you access sequential files, RMS allows you to switch between
record I/O and block I/O with each record operation, if desired. To
enable I/O switching for a record stream connected to a sequential
file, use the following procedure:
 
  - Set the FAB$V_BRO option in the FAB$B_FAC field as input to the
  Create or Open service.
  
 - Clear the RAB$L_ROP field RAB$V_BIO option as input to the Connect
  service.
  
This procedure informs RMS that it should check the RAB$V_BIO option in
the RAB$L_ROP field after each operation.
 
To do a block I/O operation:
 
  - Set the RAB$L_ROP field RAB$V_BIO option.
  
 - Invoke a block I/O service (Read, Space, or Write).
  
To do a record I/O operation:
 
  - Clear the RAB$L_ROP field RAB$V_BIO option.
  
 - Invoke a record I/O service.
  
Use care if you do choose to mix record and block I/O operations for
sequential files. When you switch operations on disk devices, the
context of the current record, the next record, and the next block
pointer is undefined. Thus, the first operation after the switch must
not use sequential record access mode. For magnetic tape devices, the
context of the next record or next block indicates the start of the
following block on the tape for the first operation after the switch.
 
As previously noted, you usually set the FAB$B_FAC field FAB$V_BRO
option only to indicate that you want to mix record I/O and block I/O
operations. If you decide that you want to perform block I/O processing
only, you can set the RAB$L_ROP field RAB$V_BIO option after you open
the file but before you invoke the Connect service. This connect-time
operation overrides the setting of the FAB$V_BRO option for the current
record stream and indicates to the Connect service that you only intend
to do block I/O for this file, thus eliminating the need to allocate
internal I/O buffers. (However, you must still allocate buffers for
block I/O operations in your application program.) If you set the
FAB$V_BRO option when you create an indexed file, the key definition
XABs for that file must be present.
 
When you access relative or indexed files, switching is available only
if you close and reopen the file. RMS does not permit both types of I/O
simultaneously. When multiple record streams are used, all record
streams must use the same type of I/O, either record I/O or block I/O.
 
You specify the I/O type when you create or open a file by selecting
either the block I/O option (FAB$V_BIO bit set) or the record I/O
option (FAB$V_BIO bit clear). For relative and indexed files, the
decision to use block I/O or record I/O for a file can be postponed, if
desired, until the record stream is connected by the following
procedure:
 
  - Set the FAB$B_FAC field FAB$V_BRO option when you are opening (or
  creating) the file.
  
 - Indicate the appropriate operation to the Connect service by either
  setting the RAB$V_BIO bit in the RAB$L_ROP for block I/O or by clearing
  it for record I/O.
  
B.3.12 Next Block Pointer (NBP)
For block I/O operations to sequential files on disk devices, RMS
maintains an internal next block pointer (NBP) that does the following
functions:
 
  - Points to the beginning of the file following execution of a
  Connect service if the RAB$V_EOF option in the RAB$L_ROP field of the
  RAB is cleared. If the RAB$L_ROP field RAB$V_EOF option is set, the NPB
  points to the block following the end of the file. The RAB$V_EOF option
  is relevant only for sequential files doing block I/O processing.
  
 - Points to the block following the highest numbered block
  transferred by a read or write operation.
  
 - Points to the next block following an operation invoked by the
  Space service.
  
An explicit Extend service is required for relative and indexed files
because RMS does not automatically extend a file's allocation when
using block I/O processing.
 
Example B-10 illustrates how to copy a file using block I/O.
 
 
  
    | Example B-10 Use of Block I/O | 
   
  
    
       
      
        .TITLE  BLOCKIO
;
; This program copies the input file to the output file.
; It illustrates block I/O using the RMS $READ and $WRITE
; macros.
;
        .PSECT  DATA,WRT,NOEXE
INFAB:  $FAB    FNM = <INFILE:>,-       ; Input file name
                FAC = <BIO,GET>         ; Block I/O read operations
INRAB:  $RAB    FAB = INFAB,-           ; Pointer to FAB
                BKT = 0,-               ; Start with current block
                UBF = REC_BUFF,-        ; Record buffer
                USZ = REC_SIZE          ;   and size
OUTFAB: $FAB    FNM = <OUTFILE:>,-      ; Output file name
                FOP = CBT,-             ; Try for contiguous file
                MRS = REC_SIZE,-        ; Maximum record size
                FAC = <BIO,PUT>,-       ; Block I/O write operations
                RAT = CR                ; Implied carriage control
OUTRAB: $RAB    FAB = OUTFAB,-          ; Pointer to FAB
                BKT = 0,-               ; Start with current block
                RBF = REC_BUFF          ; Output uses same buffer
                                        ;   as input
REC_SIZE = 1024                         ; Maximum record size
REC_BUFF:
        .BLKB   REC_SIZE                ; Record buffer
        .PSECT  CODE,NOWRT,EXE
;
; Initialization - Open input and output files and connect streams
;
        .ENTRY  BLOCKIO,^M<>            ; No registers to save
        $OPEN   FAB=INFAB               ; Open input file
        BLBC    R0,EXIT1                ; Quit on error
        $CONNECT        RAB=INRAB       ; Connect to input
        BLBC    R0,EXIT2                ; Quit on error
        MOVL    INFAB+FAB$L_ALQ,-       ; Set proper size
                OUTFAB+FAB$L_ALQ        ;   for output
        $CREATE FAB=OUTFAB              ; Create output file
        BLBC    R0,EXIT3                ; Quit on error
        $CONNECT        RAB=OUTRAB      ; Connect to output
        BLBC    R0,EXIT4                ; Quit on error
;
; Copy loop
;
READ:   $READ   RAB=INRAB               ; Get a block
        BLBS    R0,WRITE                ; Write the block
        CMPL    R0,#RMS$_EOF            ; Was error end-of-file?
        BEQL    DONE                    ; Successful completion
        BRB     EXIT2                   ; If not, signal error
WRITE:  MOVW    INRAB+RAB$W_RSZ, -      ; Set the record size
                OUTRAB+RAB$W_RSZ        ;   for output
        $WRITE  RAB=OUTRAB              ; Write the block
        BLBC    R0,EXIT4                ; Quit on error
        BRB     READ                    ; Go back for more
;
; Error Signaling
;
EXIT1:  MOVL    INFAB+FAB$L_STS,R2      ; Move STS into R2
        MOVL    INFAB+FAB$L_STV,R3      ; Move STV into R3
        BRB     EXIT                    ; Signal error
EXIT2:  MOVL    INRAB+RAB$L_STS,R2      ; Move STS into R2
        MOVL    INRAB+RAB$L_STV,R3      ; Move STV into R3
        BRB     EXIT                    ; Signal error
EXIT3:  MOVL    OUTFAB+FAB$L_STS,R2     ; Move STS into R2
        MOVL    OUTFAB+FAB$L_STV,R3     ; Move STV into R3
        BRB     EXIT                    ; Signal error
EXIT4:  MOVL    OUTRAB+RAB$L_STS,R2     ; Move STS into R2
        MOVL    OUTRAB+RAB$L_STV,R3     ; Move STV into R3
        BRB     EXIT                    ; Signal error
;
; Close files and exit
;
DONE:   $CLOSE  FAB=INFAB               ; Close input and
        $CLOSE  FAB=OUTFAB              ;   output files
        RET                             ; Return w/ success in R0
EXIT:   PUSHL   R3                      ; Push STV and STS
        PUSHL   R2                      ; on stack
        CALLS   #2, G^LIB$SIGNAL        ; Signal error
        RET                             ; Return w/ status in R0
        .END    BLOCKIO
 |   
This example program uses block I/O to transfer the contents of the
input file to the output file. The following program data statements
specify block I/O read operations from the input file by setting the
FAB$V_BIO bit (block I/O) and the FAB$V_GET bit (read) in the FAB$B_FAC
field of the input file's FAB:
 
 
  
    
       
      
INFAB:  $FAB    FNM = <INFILE>, -       ;Input file name
                FAC = <BIO,GET>,-
 |   
The following data statements specify block I/O write operations to the
output file by setting the FAB$V_BIO bit (block I/O) and the FAB$V_PUT
bit (write) in the FAB$B_FAC field of the output file's FAB:
 
 
  
    
       
      
OUTFAB: $FAB    FNM = <INFILE>, -       ;Output file name
                FAC = <BIO,PUT>,-
 |   
The input file's contents are copied until the end of file is
encountered. Any errors are signaled with the convention of using both
the STS and STV fields of the appropriate control block.
 
  
  
		
	
 
  
   |