Tuesday, November 8, 2011

RXVSAM — VSAM-enabling REXX routines

RXVSAM is a package originated by Mark Winges.  Mark is out of the programming game these days, preferring to devote his time to music, but he left behind a very useful piece of software that you can have for free.  It can be found on file 268 of the CBT Tape.  You will have to assemble the RXVSAM load module from its supplied source, but it doesn't have to be located in an authorized library, so anyone can have a VSAM-enabled REXX routine, and let me assure you that is something very useful to have on occasion.  What follows will be a very 'surface' treatment of RXVSAM just to illustrate how powerful it is.  It will not be a recitation of the RXVSAM manual. 

Once you have RXVSAM available to you as a callable load module, you have to make it available to your REXX routine:

   "LIBDEF ISPLLIB DATASET ID(...the loadlib with RXVSAM...) STACK"

and you have to allocate and open the VSAM dataset(s) you are going to work with:

   "ALLOC FI($VS) DA("ocompds") SHR REU"
   rxv_rc = RXVSAM("OPENINPUT","$VS","KSDS")

A word of warning:  RXVSAM is very fussy about its parameters.  They must be exactly the right length.  Quoted literals are best whenever possible.  With the dataset allocated and open, VSAM I/O operations may commence:

   rxv_rc = RXVSAM('READ','$VS',component,'AD0104')
   if rxv_rc > 0 then do               /* ...oops                    */
      sw.0error_found = 1
   else do
      parse var ad0104  appl 9 component 19 currver 29 bits 30

Here, a READ command is issued against a KSDS dataset previously opened as INPUT ($VS) using key 'component'.  The result of the READ is returned in variable AD0104.  Note carefully what is quoted and what is not quoted.

When the VSAM dataset is no longer needed, it must be closed by RXVSAM and FREEd:

   rxv_rc = RXVSAM("CLOSE","$VS")
   "FREE  FI($VS)"

and, of course, you must (eventually) release the LIBDEF for the RXVSAM library:


Virtually anything you can do to or with a VSAM dataset in COBOL or PL/I you can now do in REXX.  If, for instance, an ISPF table has grown beyond the limits of practicality for tables, the data can be configured as a VSAM KSDS.  To service an inquiry, read-with-key in the VSAM KSDS, and load a selection of the dataset's records to a temporary ISPF table.  All the facilities for handling ISPF tables will then be available for use on that subset of the VSAM file — the best of both worlds.

I have a large number of examples of operations using RXVSAM.  If you have questions, feel free to drop me a line.


  1. I've been using RXVSAM for a long while now, but just today I got bitten by some odd behaviour.

    I had always assumed that a browse would simply be ended by doing a keyed READ. However today I noticed that a record that I expected to be updated wasn't. I had to repeat the OPENIO on the file (which gave me a RC of 5 because the file was already open), in order to get it to perform a keyed READ properly after having done some browsing of the file.

  2. When you say "browse", I presume you're in the mode OPENIO-READGENERIC-READNEXT-CLOSE, is that right? I'm having a hard time understanding how a 'keyed-READ' would be involved.

  3. I was referring to STARTFWD or STARTBWD followed by either a READNEXT or READPREV respectively.

    I've worked out what the actual problem is. If you call RXVSAM('READNEXT'...) followed by RXVSAM('READ'), all that happens is that the word "READ" replaces the identical 4 letters from "READNEXT". Consequently RXVSAM will just do another READNEXT. Likewise if teh previous comman was READPREV.

    Having looked through the assmbler, I can see that it will not detect the change in request. To cure this, always make sure you code RXVSAM('READ '...) [note the space after read], which will ensure that a change of request is acted on.


  4. Thank you, Captain Paralytic!

    That correction just made this blog worth the effort to create it. I went and reviewed some of my own RXVSAM-based code and discovered that I have set myself up for the same sort of thing.

    It might be better to create all the RXVSAM verbs as 8-character blank-filled strings and not hard-code them in the command (a practice which just BEGS for failure).

  5. 8 character strings won't work since it needs the full strings: OPENINPUT, OPENOUTPUT, READGENERIC

    Interestingly, if you code RXVSAM('READABOOK',...) it will interpret that as if you had coded RXVSAM('READ',...).

    Look at the assembler code and you'll see why.