Take the last file and use it as jcl variable - mainframe

I have to do a job that uses the last file from a base name. For example, if I am having:
FILE.140115
FILE.140111
FILE.140101
I need to catch FILE.140115 wich has the closest date from today.
So, I would use:
//TEST010 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//OUTDD DD DSN=FILE.LISTFILE,
// DISP=(NEW,CATLG,DELETE),
// DATACLAS=(MED),
// DCB=(RECFM=VB,LRECL=125)
//SYSIN DD *
LISTCAT ENT(FILE.*) -
NAME -
OUTFILE(OUTDD)
Then, using a sort I can obtain a single file with the name of the file that I need inside. But I dont know how to use the content of this file as a variable to use it as parameter in another step.
Is there a way to do this without using CLIST? Or other ways to do what I want.
Thanks in advance!

Have you tried using a GDG? Many problems normally solved in a distributed environment with date/timestamps in file names are readily solved in a mainframe environment with GDGs.

Related

copying and pasting information between datasets

How to copy data fully from one dataset to another dataset when one of the dataset consists of dots as shown bllow ?
The dots you are seeing are most likely undisplayable data so a utility is the best bet.
There are many ways to move data around on z/OS. If you are simply trying to copy an existing dataset to another to make a copy you could use a batch utility like IEBGENER. Here is some sample JCL
//IEBGENER JOB (CCCCCCCC),'HOGSTROM',
// MSGLEVEL=(1,1),
// MSGCLASS=O,
// CLASS=A,
// NOTIFY=&SYSUID
//*
//*----------------------------------------------------------
//* IEBGENER
//*----------------------------------------------------------
//GENER02 EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DSN=USER1.TEST.DATA,DISP=SHR
//SYSUT2 DD DSN=USER1.TEST.ODATA,DISP=(,CATLG,DELETE),
// UNIT=SYSDA,SPACE=(CYL,5,RLSE),DCB=USER1.TEST.DATA
//SYSIN DD DUMMY
//
You could also use online tools like ISPF Option 3.2 to create the new dataset
and 3.3 to move / copy it.
It's not clear to me what question you're asking, or why you'd do such a thing by hand. I'd instead suggest using one of the built in z/OS tools. Specifically, IEBCOPY.
//COPYLIKE JOB MSGCLASS=H,TIME=1440
//COPYREP EXEC PGM=IEBCOPY
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DSN=SYS1.LPALIB,DISP=SHR,UNIT=3390,VOL=SER=D83RL2
//SYSUT2 DD DSN=SYS1.LPALIB.ORIG,
// LIKE=SYS1.LPALIB,
// DISP=(NEW,KEEP),VOL=SER=D83RL2,UNIT=3390
//SYSIN DD *
/*
Also, as a note, the source dataset doesn't consist of dots, it consists of undisplayable data.

JCL - MVS: how to retrieve result from submiting MVS command in Batch

Morning guys,
After submitting a MVS command in Batch, I wonder if it is possible to print the result in a seq file. Thanks for your time.
//S02IEBG EXEC PGM=IEBGENER
//SYSUT2 DD SYSOUT=(A,INTRDR),DCB=BLKSIZE=23440
//SYSIN DD DUMMY
//SYSOUT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD *,DLM=$$
/*$VS,'$DQ'
$$
It isn't clear from your question, but if you mean "after submitting your job, can you capture output to a dataset", I would suggest you use the XDC line command in SDSF. If you want a specific part of the output, use the ? line command first to show each of the outputs, then XDC on the one you want to save.
Yes it is possible to write the SYSOUT to a sequential file. I have done this before, but I would not recommend it unless you absolutely need to.
Your system should have some SYSLOG management system (like SMR/JMR or similar), where you can browse the SYSOUTs that a job has produced. Don't get me wrong, I realize that this isn't fool proof. There are times when you may need to write the SYSOUT to a file. The reason I needed to was because I looping with a lot of debugging displays and needed to have a lot lines to help me debug.
If you want to make sure that the SYSOUT goes to a file all you need to do is put the file after the SYSOUT:
//S02IEBG EXEC PGM=IEBGENER
//SYSUT2 DD SYSOUT=(A,INTRDR),DCB=BLKSIZE=23440
//SYSIN DD DUMMY
//SYSOUT DD DSN=YOUR.SYSOUT.FILE,
// DISP=(NEW,CATLG,DELETE),
// UNIT=TEST,SPACE=(TRK,(2,1),RLSE),
// DCB=(LRECL=080,BLKSIZE=0,RECFM=FB)
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD *,DLM=$$
You can alter the size of the file if you need to by editing the SPACE parameter. If you plan on running this job more than once, you will need to add a delete step before this, or make your SYSOUT file a GDG that can be incremented. Otherwise, the DISP of NEW will not work.
This can be done with any DD name as long as you know what the proper file allocation is.
I believe that the following may work. That is assuming that you want to capture the output from the DQ command :-
//SDSF EXEC PGM=SDSF
//ISFOUT DD SYSOUT=*
//CMDOUT DD DSN=YOUR.DATASET,
// DISP=(,CATLG,DELETE),
// DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0),
// SPACE=(CYL,(1,1)),UNIT=SYSDA
//ISFIN DD *
SET CONSOLE BATCH
SET DELAY 60
/$ DQ
PRINT FILE CMDOUT
ULOG
PRINT
PRINT CLOSE
/*
//
Obviously this may need to be tailored according to your site's requirement.
You may find Issuing MVS or JES commands helpful.
Addition Re Comment :-
I did try the SDSF but I am not authorized to use it, which is why I
am looking for another way.
Perhaps then using TSO/E (REXX) as per :-
From TSO/E, you can establish an extended MCS console session using
the TSO/E CONSOLE command. After you activate a console session, you
can issue MVS™ system and subsystem commands and obtain command
responses. This appendix describes the different commands and
functions you can use in REXX execs to set up and use a console
session.
Writing REXX Execs to perform MVS operator activities
However, authority may be an issue if not immediately perhaps as soon as someone cottons on to you getting around the doors already closed.
This may work (I don't have the facilities to test it) :-
/* REXX */
ADDRESS TSO 'CONSPROF SOLDISPLAY(NO)'
ADDRESS TSO 'CONSOLE ACTIVATE'
ADDRESS CONSOLE '$DQ'
/* retrieve output command */
max_iterations = 100
DO i = 1 to max_iterations
messages_remaining = GETMSG('line.','SOL',,,10)
IF messages_remaining = 0 THEN leave
END
/* Done so echo retrieved messages
say 'Messages Retrieved are :-'
DO i = 1 to line.0
say '*** ' line.i
END
ADDRESS TSO 'CONSOLE DEACTIVATE'
EXIT
You'd need to wrap that into your batch job, so you may find the following helpful
How can I run my Rexx program as a batch job?.
Method 2 would be appropriate, as you want a TSO/E environment
A solution could be speaking to those responsible for denying access to SDSF, This could result in authority being given. There again it may result in the open doors such as being able to issue JES commands being shut.
You probably have access to SDSF to view the output.
Next to the job you want to print type xdc this will pop up a panel for dataset allocation(or it can be already existing one). Once done it will print the output and close it.
If You need just a output of a certain step/sysout you can type ? next to the job in SDSF. This will give you the list of the outputs. Same as before type xdc next to the one you picked and allocate a dataset.
This can also be done to your TSO session if you use the commands directly and need to have a history of it. Although this will only work until you close the SDSF ULOG.

Setting PATH in IEBGENER from file

I'm trying to set the PATH parameter in a IEBGENER step in a JCL from a file. But I can't seem to get it to work.
Here is what the original step, that works just fine, looks like:
//COPY EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSUT1 DD *
Some text
//SYSUT2 DD PATH='/local/Folder1/File1',
// PATHDISP=(KEEP,KEEP),
// PATHOPTS=(OWRONLY,OCREAT,OEXCL),
// PATHMODE=(SIRUSR,SIWUSR)
What I want to do is set the PATH parameter in SYSUT2 from a file that is written in some previous step. Something like this:
BROWSE TEST.FILE1 Line 0000000000 Col 001 080
Command ===> Scroll ===> CSR
********************************* Top of Data **********************************
TPATH='/local/Folder1/File1'
******************************** Bottom of Data ********************************
//SETPATH SET DSN=TEST.FILE1,DISP=SHR
//*
//COPY EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//SYSUT1 DD *
Some text
//SYSUT2 DD PATH='&TPATH',
// PATHDISP=(KEEP,KEEP),
// PATHOPTS=(OWRONLY,OCREAT,OEXCL),
// PATHMODE=(SIRUSR,SIWUSR)
This of course complains about no variable TPATH in the JCL, which logically makes sense as it can't find the variable name in the JCL.
Also tried putting the entire SYSUT2 in a separate file, but without success.
A "good enough" compromise would be to concatenate a file prefix with a date and time parameter, but that would only work in production when the job is run via a scheduler (with OPCSCAN or similar). Not in test where I submit the job myself, or is it possible to do that without a scheduler?
'/local/Folder1/File' & iDate & iTime -- You get the point.
Any ideas much appreciated!
One way to do this would be to write the SYSUT2 DD statement to a member in a separate PDS or PDSE, then INCLUDE that member in your IEBGENER step. The separate PDS or PDSE must be specified in a JCLLIB statement.
You could also run BPXBATCH and use cp instead of IEBGENER to copy your data.
If you have the Dovetail Technologies Co:Z Toolkit installed, fromdsn might be what you're looking for.

How to create a member in an existing pds using jcl

I've used the below jcl:
//STEP1 EXEC PGM=IEBGENER
//SYSUT1 DD DUMMY,RECFM=FB,LRECL=80
//SYSUT2 DD DSN=RK.MYDIR.FILES(NEW1),DISP=(SHR)
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
I was able to create it. But i can't understand the code here. Is there any possibility to create using IEFBR14. If not this is the nly way. Please kindly explain me the code. Thank you
It can't be done with IEFBR14
IEBCOPY is more appropriate:
http://publib.boulder.ibm.com/infocenter/zos/basics/index.jsp?topic=/com.ibm.zos.zdatamgmt/zsysprogc_utilities_IEBCOPY.htm
This is the reference which helps explain IEBGENER:
http://publib.boulder.ibm.com/infocenter/zos/basics/index.jsp?topic=/com.ibm.zos.zdatamgmt/zsysprogc_utilities_IEBGENER.htm
If you're interested in the reason why, understand that IEFBR14 doesn't actually open any of the DD statements you code in your JCL. Rather, it's just a shorthand way to drive the system allocation (and deallocation) routines. Indeed, if you were to look at an assembler listing of iEFBR14, you'd find it's only two instructions: set the R15 return code to zero, and exit.
With batch processing, the idea is that the system (JES plus the batch initiator) should do a lot of the work before an application even starts. Thus, if you allocate a new dataset, or reference (say) a tape device that takes time for the operator to mount, the system does all this for you before your program even starts. IEFBR14 is a convenient way to use the system allocation routines to allocate files using these capabilities of JCL.
But there's a catch when it comes to accessing PDS datasets in JCL, like you're trying to do.
When you specify DSN(MEMBER) syntax in JCL, the allocation routines don't particularly care about the MEMBER part - turns out, this isn't a function of the initiator, but is instead implemented in OPEN/CLOSE. In your example, allocation verifies that the dataset exists (since you coded DISP=SHR), and when a program OPENs the DD statement, the OPEN routines automatically issue BPAM FIND/POINT/STOW to get you to the PDS member you specified. This is how your PDS member gets created, and so you need to use a program that actually OPENs the file (IEBGENR, IEBUPDTE, IEBCOPY, IDCAMS, etc would all work).
One small unrelated comment is that you might want to be careful about updating datasets (especially PDS) using DISP=SHR. If you manage to get the timing wrong, two of these jobs could in theory run at exactly the same time, and this would likely cause corruption to your dataset. Unless you're certain you're the only task accessing the PDS, it's safer to use DISP=OLD in this case.
If you'd like to create multiple members at once, I suggest IEBUPDTE.
From IBM:
This basic example uses IEBUPDTE to add two JCL procedures to the data set named MY.PROCLIB:
//ADDPROC1 JOB 1,SMCHUGH,MSGCLASS=X
// EXEC PGM=IEBUPDTE
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DISP=OLD,DSN=MY.PROCLIB
//SYSUT2 DD DISP=OLD,DSN=MY.PROCLIB
//SYSIN DD DATA
./ ADD LIST=ALL,NAME=MYJOB1
//STEP1 EXEC=SUZNX1
//PRINT DD SYSOUT=A
// (more JCL for MYJOB1)
//SYSUDUMP DD SYSOUT=* (last JCL for MYJOB1)
./ REPL LIST=ALL,NAME=LASTJOB
//LIST EXEC PGM=SUZNLIST
// (more JCL for this procedure)
//* LAST JCL STATEMENT FOR LASTJOB
./ ENDUP
/*
This creates one new member, MYJOB1, but you can see that it can also replace members (LASTJOB).
http://publib.boulder.ibm.com/infocenter/zos/basics/topic/com.ibm.zos.zdatamgmt/zsysprogc_utilities_IEBUPDTE.htm
If you are copying the contents of a DSN into the new member, use IEBGENER.
To set the attributes of the new DSN dynamically use the LIKE parameter.
For example (using Mikes example above)
//STEP1 EXEC PGM=IEBGENER
//SYSUT1 DD DISP=SHR,DSN=your.input.dataset
//SYSUT2 DD DISP=(,CATLG,DELETE),DSN=your.output.dataset,
// LIKE=your.input.dataset
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY <-- no CONTROL statements
The LIKE attribute lets you easily create a new dataset, using the attributes of the dataset you specify, I also changed the disposition to reflect what a new DSN should be set to.
Warning! -- in re using IEBGENER with SYSUT2 DD DSN=PDS(MEMBER): Don't forget to specify the MEMBER name -- if you do, IEBGENER will overwrite your PDS from the beginning with whatever it finds in SYSUT1, starting with ruining your PDS directory!
The IEBGENER utility is used to copy a single file.
The SYSUT1 DD name is used to supply the INPUT or file to be copied from.
The SYSUT2 DD name is the OUTPUT file.
The SYSIN DD provides the CONTROL statements (if any).
//STEP1 EXEC PGM=IEBGENER
//SYSUT1 DD DISP=SHR,DSN=your.input.dataset
//SYSUT2 DD DISP=SHR,DSN=your.output.dataset
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY <-- no CONTROL statements
Note that the file/dataset can be a sequential dataset or a member of a partitioned dataset.
//SYSUT1 DD DISP=SHR,DSN=your.input.dataset(member)
//SYSUT2 DD DISP=SHR,DSN=your.output.dataset(member)

How to pass arguments to REXX program through JCL

Can we pass arguments to a REXX program from JCL?
I suppose, JCL PARM can be used as we use for passing arguments to COBOL programs.. Do put your ideas here...
You want EXEC PGM=IRXJCL,PARM='member_name exec_args'. SYSEXEC should point to the PDS containing member name. SYSTSIN is the input for PULL, SYSTSPRT is the output DD for SAY
Check out the "Using REXX in TSO/E and Other MVS Address Spaces" chapter in the "TSO/E Rexx User Guide" book (SA22-7791) for a full example.
An added note: If your REXX exec uses ISPF services, you can run it in batch with PGM=IKJEFTxx (xx being a variable suffix) and allocating ISPxLIB in the job step.
If the parameters together with the REXX member name exceeds 100 bytes, the method mentioned by Ron Patterson won't work as JCL syntax only allows a maximum paramater length of 100 bytes. In this case I recommend using IKJEFTxx (already posted by Tony). You then have to pass the REXX program name as instream data to SYSTSIN. The parameters to this program can simply written behind the program name. When you need more than one line, use the hyphen as last character of a line to indicate the concatenation with the following line.
Example:
//EXAMPLE EXEC PGM=IKJEFT01,REGION=4096K,DYNAMNBR=30
//SYSPRINT DD SYSOUT=*
//SYSEXEC DD DISP=SHR,DSN=YOUR.REXX.LIBRARY
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
SCHLABB PARAMETER1 PARAMETER2 PARAMETER3 -
VERY_LONG_PARAMETER4 -
LAST_PARAMETER5
/*
//
I was getting RC (-3) for basic EXECIO, LIBDEF, commands when I tried running IRXJCL. I wish there was better documentation on what IRXJCL can and can not do.
Finally followed the approach from the below link, to dynamically pass values to a REXX by writing them to a file and reading from the file. How to run dymanic SQL through IKJEFT01 Utility?

Resources