Dynamically Allocating Ddnames on MVS

Allocating files in TSO can be a chore if you use a large number of datasets, use some datasets infrequently, customize your JCL for each job or, even worse, allocate just about everything to ensure that nothing is left out.

After doing all of the above at one time or another at our customer Sedgwick James, we devised a neat and efficient way for FOCUS to help us allocate only what we needed and only when we needed it.

The Problem

We had access to and reported from over 100 FOCUS, VSAM, FIX, and decode files with new files added on a regular basis. Just keeping track of the ddnames and dataset names was a chore, as was deciding where to allocate each file.

When we used a JCL to allocate the file, either the JCL would have to be changed frequently or be customized for each job, otherwise everything had to be allocated at runtime. If we allocated the ddname in a FOCEXEC, it was possible to allocate just what we needed. But this only works when FOCUS is running online.

If the same FOCEXEC is run in batch, FOCUS ignores the TSO ALLOCATE statements, and the FOCEXEC bombs. So maintaining the allocations in the JCL seemed the only viable option.

But what would happen when we added a new file? Or when we created a new version of a file with a new dataset name? We would have to add the new dataset to the existing JCL or update the old dataset name wherever it was used (whether in a FOCEXEC or in JCL). A little investigation proved that the DYNAMcommand could be used to provide a solution.

The Technique

The first step is to create a set of FOCEXECs so that each of about 100 ddnames (or MFDs) has a corresponding identically named FOCEXEC in a separate PDS. Each FOCEXEC contains the FOCUS code to verify the existence of and dynamically allocate the affiliated file. For example, the CAR FOCEXEC shown in Figure 1 allocates the CAR file. The numbered paragraphs that follow correspond to the numbered segments of code.

Figure 1

-******************************************************
-* FOCEXEC: CAR
-* DYNAM command and verification for file CAR
-* Created on 96/2/26
-*******************************************************
1. -DEFAULT &1=' '
2. DYNAM ALLOC FI CAR DA TSOFOC1.FOCUS.CAR SHR REUSE
   -RUN
3. EX DYNAMERR DYNAM_DD=CAR , DYNAM_RPT=&1
-*******************************************************

1.  &1 is a passed parameter, which is the name of the FOCEXEC that issues the -INCLUDE statement. So if the allocation fails, we will know in which FOCEXEC the error occurred (step 3). If no value is passed or -SET in the calling FOCEXEC, the default is a blank; this may occur if an online application or an ad hoc report is being run.
2.  The DYNAM command is issued for a shared (SHR) file, and REUSE eliminates the need for a DYNAM FREE FILE ddname command.
3.  The verification FOCEXEC, DYNAMERR, is executed and is passed both the value of the ddname (&DYNAM_DD) and the calling FOCEXEC (&DYNAM_RPT).

The DYNAMERR FOCEXEC is shown in Figure 2. The following numbered paragraphs correspond to the numbered segments of code.

1.  Set the default values if no values have been passed.
2.  Use the -? TSO DDNAME command to check if the ddname has been allocated. In this case, &DSNAME will either be populated with the ddname if the file was allocated or blank if the allocation was unsuccessful.
3.  If the allocation was successful (&DSNAME = ddname), branch to -DYNAM_END to continue processing. Otherwise print an error report (step 4).
4.  Allocate a file that we know is always available. If it has not been allocated (&DSNAME = blank), allocate it. Otherwise branch to -ERROR and continue with the error report.
5.  Set up messages to be embedded in the HEADING of the error report through amper variables (step 6).
6.  Produce a HEADING for the error report from the file previously allocated in step 4 by reading in one record (RECORDLIMIT EQ 1) and not printing it (NOPRINT). This produces a report containing only a heading.
7.  If the allocation failed, we do not want the FOCEXEC to continue processing, so we -QUIT out of the request. This flushes the FOCSTACK and halts the FOCEXEC.
8.  If the allocation was successful, we branch here and continue with the calling FOCEXEC.

Figure 2

-************************************************************************
-* FILENAME: DYNAMERR
-* PURPOSE: Checks if a DYNAM Allocate was successful.
-* If Not - Prints out Error Message and STOPS execution.
-************************************************************************
1. -DEFAULTS &DYNAM_DD='XXXXXXXX', &DYNAM_RPT=' ', &&RPT=' '
-* CHECK IF DATA SET HAS BEEN ALLOCATED.
2. -? TSO DDNAME &DYNAM_DD
3. -IF &DSNAME NE ' ' THEN GOTO DYNAM_END;
-* THE DATASET WAS NOT FOUND.
-*------------------------*
4. -? TSO DDNAME REPTFILE
-IF &DSNAME NE ' ' THEN GOTO ERROR;
DYNAM ALLOC FI REPTFILE DA TSOF0C1.FOCUS.REPTFILE SHR REUSE
-*-----------------------------------*
5. -ERROR
-SET &RPT = IF &DYNAM_RPT NE ' ' THEN &DYNAM_RPT |' ' ELSE
- IF &&RPT NE ' ' THEN &&RPT |' ' ELSE 'UNKNOWN ';
-SET &RPT = EDIT(&RPT,'99999999') |' *****';
-SET &DD = IF &DYNAM_DD EQ ' ' THEN 'UNKNOWN ' ELSE
- &DYNAM_DD |' ';
-SET &DD = EDIT(&DD,'99999999') |' *****';
6. TABLE FILE REPTFILE
HEADING
"*****"
"<38 ***** ERROR ALLOCATING THE DATASET: &DD <89>*****"
"<38 ***** *****"
"<38 ***** ERROR ***** ERROR ***** ERROR ***** ERROR *****"
PRINT PROGNAME NOPRINT
IF RECORDLIMIT EQ 1
END
-RUN
7. -QUIT
8. -DYNAM_END   
-*******************************************************

Figure 3 shows how the technique is actually implemented in a FOCEXEC. The -INCLUDE ddname statement in each FOCEXEC allocates the file in both online and batch FOCUS.

Figure 3

-******************************************************
-* FOCEXEC: CARREPT
-*Print data from the car file
-*****************************************************
-INCLUDE CAR   
TABLE FILE CAR
"CAR REPORT USING DYNAM -INCLUDE ddname FILES

Advantages

This technique has many advantages, but we also found a few disadvantages that we'll share with you. First, here are the pros:

It is faster than using just the TSO ALLOCATE command because the DYNAM command is executed within the FOCUS task.
FOCEXECs can be run in batch or online.
No customized JCL is needed; one JCL template suffices.
FOCUS code can handle error checking.
Ad hoc reporting is easy: Just -INCLUDE the DYNAM FOCEXEC (-INCLUDE ddname).
It is unnecessary to remember long dataset names.
Maintenance is easy. When a dataset needs to be added or changed, you only need to change the ddname FOCEXEC or add a new one.
The technique is easy to manage and simple to implement.

Disadvantages
A separate PDS should be maintained for these FOCEXECs. Although this eases maintenance and aids in documentation, it is an additional task.
Any new FOCEXECs should not have the same name as any of the FOCEXECs that have names corresponding to ddnames. Any previously existing FOCEXECs also will have to be renamed to avoid naming conflicts.
Creating the new FOCEXECs is an additional task. Fortunately, we had a FOCUS database that stored the ddnames and the dsnames so we were able to dynamically create the -INCLUDE ddname FOCEXECs using the TABLE command and Dialogue Manager.

This technique worked to decrease the development time needed for reports. It is almost self-documenting and, by keeping the FOCEXECs separate, this provides a good example of code reuse. Even if your site or department has access to only a handful of files, it may pay to implement this strategy.

Back Next