Você está na página 1de 4

Synthesis of Job Information from Mainframe using SAS Tool

Overview
The objective of this document is to provide an overview of the SAS tool used in extracting the job
information from Mainframe JCL. The functionality of the tool is to extract all the information from
the JCL, like Job name, Programs Used, Input filenames and Output filenames. The tool will select and
search all the members of the PDS library whose name match with the pattern passed as parameter
(PARM, SYSPARM) from the JCL.

System Requirements
o Mainframe system with access to use TSO BATCH facility
o Z/OS or OS/390 operating system in Mainframe
o SAS software Version 8 or above.

SAS Code

options symbolgen;
data _null_;
a=upcase(compress("&sysparm."));
pos = index(a,',');
if pos = 0 then abort 5;
part1 = trim(left(scan(a,1,',')));
part2 = substr(a,pos+1,length(a)-pos);
if length(part1)=0 or length(part2)=0 then abort 5;

call symput('lib',compress(part1));

pos = index(part2,'*');
p1 = trim(left(scan(part2,1,'*')));
if pos > 0 and pos < length(part2) then
p2 = substr(part2,pos+1,length(part2)-pos);
else p2="";
call symput('p1',compress(p1));
call symput('p2',compress(p2));
run;

proc source indd=finput dirdd=seqdd noprint nodata noalias;

data _null_;
p1=compress(symget('p1'));
p2=compress(symget('p2'));

FILE memdd;
INFILE seqdd ;
input memname $8. ;
memname=trim(left(memname));
if length(memname) > 0 and length(p1)>0;
if substr(memname,1,length(p1))= p1;
if p2="" or length(p2)=0 or
(length(p2) > 0 and
substr(memname,length(memname)-length(p2)+1,length(p2))=p2);
x = compress("&lib.("||memname||")") ;
put x;
run;

data _null_ ;
format j s d recs 5.;
length jclline $80. filename $44. jobn $8.;
array jobnames{15000} $8. jn1-jn15000 ;
array inputfiles{15000} $50. ipf1-ipf15000 ;
array outputfiles{15000} $50. opf1-opf15000 ;
array programs{15000} $8. pgm1-pgm15000 ;
retain filename jobn;
retain ic oc pc 0;
retain jobnames programs inputfiles outputfiles;

INFILE memdd eof=endlist;


input fullname $44.;
fullname = trim(left(fullname));
INFILE dummy filevar=fullname end=endmember;
do until(endmember);
input jclline $80.;
if substr(left(jclline),1,3) ne '//*' ;
j=index(upcase(jclline),' JOB ') ;
s=index(upcase(jclline),'DSN=') ;
d=index(upcase(jclline),'DISP=') ;

if j >0 then do;


jobn = substr(jclline,3,8);
pc = max(pc,ic,oc);
ic = max(pc,ic,oc);
oc = max(pc,ic,oc);
end;

if s >0 then do;


filename = substr(jclline,s+4,80-(s+4));
filename = scan(filename,1,',');
end;
if d >0 and ( index(jclline,'NEW') >0 OR
index(jclline,'MOD') >0 ) then do;
oc+1;
jobnames{oc} = jobn ;
outputfiles{oc} = filename;
end;
if d >0 and index(jclline,'SHR') >0 then do;
if index(filename,'SASLIB') >0 then do;
x = index(filename,'(');
y = index(filename,')');
filename = substr(filename,x+1,y-x-1);
pc+1;
programs{pc} = filename;
jobnames{pc} = jobn ;
end;
else do;
ic+1;
inputfiles{ic} = filename;
jobnames{ic} = jobn ;
end;
end;
end;
return;

endlist:
file FOUTPUT noprint;
recs = max(ic,oc,pc);
do i=1 to recs;
put jobnames{i} "|" programs{i} "|"
inputfiles{i} "|" outputfiles{i};
end;
run;
//*

Execution Procedure
Copy the code above into a dataset and then run using the sample JCL below.
//USERID01 JOB ACCTINFO,'TEST SAS',REGION=6M,
// CLASS=A,MSGCLASS=X,TIME=(,59),NOTIFY=&SYSUID
//STEP0010 EXEC SAS,
// PARM='SYSPARM="prodqual.alljobs.jcllib,bxyz*"'
//WORK DD UNIT=(SYSDA,10),SPACE=(CYL,(10,10))
//FINPUT DD DSN=PRODQUAL.ALLJOBS.JCLLIB,DISP=SHR
//SEQDD DD DSN=USERID.TEST.LST1,
// DISP=(NEW,CATLG,DELETE),SPACE=(CYL,(1,1)),UNIT=SYSDA
//MEMDD DD DSN=USERID.TEST.LST2,
// DISP=(NEW,CATLG,DELETE),SPACE=(CYL,(1,1)),UNIT=SYSDA
//FOUTPUT DD DSN=USERID.TEST.OUT,
// DISP=(NEW,CATLG,DELETE),SPACE=(CYL,(1,1)),UNIT=SYSDA
// DCB=(RECFM=FB,LRECL=200)
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSIN DD DSN=<Dataset with Code>,DISP=SHR

Test Case / Test Results

Assume that the PDS PRODQUAL.ALLJOBS.JCLLIB has members like BXYZ001S, BXYZ002S,
BXYZ003S, and BXJZ005S. Then this tool will select only members starting with BXYZ, since BXYZ*
is passed as parameter.

Create a PDS and copy JCL members BXYZ001S, BXYZ002S, BXYZ003S, BXJZ005S. JCL will look
typically as below.

//BXYZ001S JOB PRDSAS,'SA JOB',MSGCLASS=X,CLASS=X


//STEP0010 EXEC SAS,TIME=(90),
// OPTIONS='MACRO CHARCODE DQUOTE NOSTATS CAPSOUT'
//WORK DD UNIT=SYSDA,SPACE=(CYL,(150,50)),BLKSIZE=27648
//SASLOG DD SYSOUT=T
//SASLIST DD SYSOUT=*
//MODPG DD DSN=PRODQUAL.ALLJOBS.SASLIB(BCTL0101),
// DISP=SHR
//IN1 DD DSN=PRODQUAL.PB.INPUT1,
// DISP=SHR
//IN2 DD DSN=PRODQUAL.PB.INPUT2,
// DISP=SHR
//IN3 DD DSN=PRODQUAL.PB.INPUT3,
// DISP=SHR
//OUT1 DD DSN=PRODQUAL.PB.OUTPUT1,
// DISP=SHR
//OUT2 DD DSN=PRODQUAL.PB.OUTPUT2,
// DISP=SHR
//SYSIN DD DSN=PRODQUAL.ALLJOBS.SASLIB(BCTL0102),
// DISP=SHR

//BXYZ002S JOB PRDSAS,'SA JOB',MSGCLASS=X,CLASS=X


//STEP0010 EXEC SAS,TIME=(90),
// OPTIONS='MACRO CHARCODE DQUOTE NOSTATS CAPSOUT'
//WORK DD UNIT=SYSDA,SPACE=(CYL,(10,5)),BLKSIZE=27648
//SASLOG DD SYSOUT=T
//SASLIST DD SYSOUT=*
//IN1 DD DSN=PRODQUAL.PB.INPUT1,
// DISP=SHR
//OUT1 DD DSN=PRODQUAL.PB.OUTPUT3,
// DISP=SHR
//OUT2 DD DSN=PRODQUAL.PB.OUTPUT4,
// DISP=SHR
//SYSIN DD DSN=PRODQUAL.ALLJOBS.SASLIB(BCTL0201),
// DISP=SHR

//BXYZ003S JOB PRDSAS,'SA JOB',MSGCLASS=X,CLASS=X


//STEP0010 EXEC SAS,TIME=(90),
// OPTIONS='MACRO CHARCODE DQUOTE NOSTATS CAPSOUT'
//WORK DD UNIT=SYSDA,SPACE=(CYL,(150,50)),BLKSIZE=27648
//SASLOG DD SYSOUT=T
//SASLIST DD SYSOUT=*
//MODPG DD DSN=PRODQUAL.ALLJOBS.SASLIB(BCTL0101),
// DISP=SHR
//IN1 DD DSN=PRODQUAL.PB.INPUT4,
// DISP=SHR
//OUT1 DD DSN=PRODQUAL.PB.OUTPUT5,
// DISP=SHR
//SYSIN DD DSN=PRODQUAL.ALLJOBS.SASLIB(BCTL0202),
// DISP=SHR

Output of the job will look like below. Note that the fields are delimited by pipe symbol. Format of the
output is Job name | Program name | Input dataset | Output dataset.
BXYZ001S | BCTL0101 | PRODQUAL.PB.INPUT1 | PRODQUAL.PB.OUTPUT1
BXYZ001S | BCTL0102 | PRODQUAL.PB.INPUT2 | PRODQUAL.PB.OUTPUT2
BXYZ001S | | PRODQUAL.PB.INPUT3 |
BXYZ002S | BCTL0201 | PRODQUAL.PB.INPUT2 | PRODQUAL.PB.OUTPUT3
BXYZ002S | | | PRODQUAL.PB.OUTPUT4
BXYZ003S | BCTL0202 | PRODQUAL.PB.INPUT4 | PRODQUAL.PB.OUTPUT5

Benefits
o This is an excellent tool for job analysis. Information from thousands of members can be easily
synthesized using this tool. Manual effort is extremely less.
o The pattern is passed as parameter. So it is easy to control the selection of member list.
o Asterisk wild character (*) can be used in SYSPARM. So several selection criteria like BXYZ*1,
BXYZ*, BXY*Z1 can be used.
o This tool will eliminate the limitation of selecting only 200 members using PROC SOURCE option in
SAS in Z/OS and UNIX.
o The output is pipe delimited. Hence it can be downloaded into excel sheet for analysis.
o The output has job name in all line, to enable filtering in excel.
o The library name (i.e. the PDS which needs to be searched) and the member pattern type are
passed via the submitting job. So the code need not be modified.

Limitation
o The tool is designed to pull static filenames. If symbolic references are used, then the tool needs
to be run against the job log. The PDS member names need to be same as job log. Otherwise the
filename created also will have symbols.
o Multiple wild characters cannot be used. For ex BXYZ*1*1, BXYZ**1, BXYZ%1*1 etc will produce
unexpected results.

Scope of Improvement / Future enhancements


o The tool can be enhanced to produce other information - DCB Information like record length,
record format, Media type (disk/tape), Step name, Procedures being called, Load module names
etc. from the JCL.

References
“SAS 9.1 Companion for Z/OS” System manual from website www.support.sas.com

Você também pode gostar