JCL - 基本排序技巧

企业界可以使用实用程序实现的日常应用程序要求如下所示:

1.一个文件有100条记录.需要将前10条记录写入输出文件.

//JSTEP020 EXEC PGM=ICETOOL                                          
//TOOLMSG  DD SYSOUT=*                                               
//DFSMSG   DD SYSOUT=*                                               
//IN1      DD DSN=MYDATA.URMI.STOPAFT,DISP=SHR    
//OUT1	   DD SYSOUT=*
//TOOLIN   DD *                                                      
  COPY FROM(IN1) TO(OUT1) USING(CTL1)                                  
/*
//CTL1CNTL DD *                        
  OPTION STOPAFT=10               
/*


选项STOPAFT将在第10条记录后停止读取输入文件并终止程序.因此,将10条记录写入输出.

2.输入文件具有相同员工编号的一个或多个记录.将唯一记录写入输出.

//STEP010  EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=*                                                
//SORTIN   DD DSN=MYDATA.URMI.DUPIN,DISP=SHR
//SORTOUT  DD SYSOUT=*
//SYSIN    DD *            
  SORT FIELDS=(1,15,ZD,A) 
  SUM FIELDS=NONE          
/*


SUM FIELDS = NONE删除SORT FIELDS中指定字段的重复项.在上面的示例中,员工编号位于字段位置1,15.输出文件将包含按升序排序的唯一员工编号.

3.覆盖输入记录内容.

//JSTEP010 EXEC PGM=SORT                                             
//SORTIN   DD DSN= MYDATA.URMI.SAMPLE.MAIN,DISP=SHR       
//SORTOUT  DD SYSOUT=*                 
//SYSPRINT DD SYSOUT=*                                               
//SYSOUT   DD SYSOUT=*                                               
//SYSIN    DD *                                                      
 OPTION COPY                                                         
  INREC OVERLAY=(47:1,6)                      
/*

在输入文件中,位置1,6的内容被覆盖到位置47,6,然后复制到输出文件. INREC OVERLAY操作用于在复制到输出之前重写输入文件中的数据.

4.将序列号添加到输出文件.

//JSTEP010 EXEC PGM=SORT                                             
//SORTIN   DD *
  data1
  data2
  data3
/*
//SORTOUT  DD SYSOUT=*                 
//SYSPRINT DD SYSOUT=*                                               
//SYSOUT   DD SYSOUT=*                                               
//SYSIN    DD *                                                      
 OPTION COPY                                                         
 BUILD=(1:1,5,10:SEQNUM,4,ZD,START=1000,INCR=2)                      
/*

输出将是:

data1    1000
data2    1002
data3    1004


在位置10的输出中添加4位序列号,从1000开始并递增2每条记录.

5.将Header/Trailer添加到输出文件.

//JSTEP010 EXEC PGM=SORT                                             
//SORTIN   DD *
  data1
  data2
  data3
/*
//SORTOUT  DD SYSOUT=*                 
//SYSPRINT DD SYSOUT=*                                               
//SYSOUT   DD SYSOUT=*                                               
//SYSIN    DD *                                                      
 SORT FIELDS=COPY                                                     
  OUTFIL REMOVECC,                                                     
  HEADER1=(1:C'HDR',10:X'020110131C'),                    
  TRAILER1=(1:C'TRL',TOT=(10,9,PD,TO=PD,LENGTH=9)) 
/*

输出将是:

HDR       20110131
data1    
data2    
data3 
TRL       000000003

TOT计算输入文件中的记录数. HDR和TRL作为标识符添加到标题/预告片中,这是用户定义的,可以根据用户的需要进行自定义.

6.条件处理

//JSTEP010 EXEC PGM=SORT                                             
//SORTIN   DD *
  data1select
  data2
  data3select
/*
//SORTOUT  DD SYSOUT=*                 
//SYSPRINT DD SYSOUT=*                                               
//SYSOUT   DD SYSOUT=*                                               
//SYSIN    DD *           
  INREC  IFTHEN=(WHEN=(6,1,CH,NE,C' '),BUILD=(1:1,15),
         IFTHEN=(WHEN=(6,1,CH,EQ,C' '),BUILD=(1:1,5,7:C'EMPTY    ') 
  OPTION COPY                                                     
/*

输出将是:

data1select   
data2 EMPTY  
data3select

根据文件的第6个位置,输出文件的BUILD会有所不同.如果第6个位置是SPACES,则附加文本"EMPTY"输入记录.否则,输入记录按原样写入输出.

7.备份文件

//JSTEP001 EXEC PGM=IEBGENER                                       
//SYSPRINT DD SYSOUT=*                                             
//SYSIN    DD *                                                    
//SYSOUT   DD SYSOUT=*                                             
//SORTOUT  DD DUMMY                                                
//SYSUT1   DD DSN=MYDATA.URMI.ORIG,DISP=SHR                     
//SYSUT2   DD DSN=MYDATA.URMI.BACKUP,DISP=(NEW,CATLG,DELETE),
//             DCB=*.SYSUT1,SPACE=(CYL,(50,1),RLSE)

IEBGENER将SYSUT1中的文件复制到SYSUT2中的文件中.请注意,SYSUT2中的文件采用与上例中SYSUT1相同的DCB.

8.文件比较

//STEP010  EXEC PGM=SORT                                              
//MAIN     DD *
  1000
  1001
  1003
  1005
//LOOKUP   DD *
  1000
  1002
  1003
//MATCH    DD DSN=MYDATA.URMI.SAMPLE.MATCH,DISP=OLD
//NOMATCH1 DD DSN=MYDATA.URMI.SAMPLE.NOMATCH1,DISP=OLD
//NOMATCH2 DD DSN=MYDATA.URMI.SAMPLE.NOMATCH2,DISP=OLD 
//SYSOUT   DD SYSOUT=*                                                       
//SYSIN    DD *                                                       
  JOINKEYS F1=MAIN,FIELDS=(1,4,A)                            
  JOINKEYS F2=LOOKUP,FIELDS=(1,4,A)                               
  JOIN UNPAIRED,F1,F2                                                 
  REFORMAT FIELDS=(?,F1:1,4,F2:1,4)                                
  OPTION COPY                                                         
  OUTFIL FNAMES=MATCH,INCLUDE=(1,1,CH,EQ,C'B'),BUILD=(1:2,4)                                                
  OUTFIL FNAMES=NOMATCH1,INCLUDE=(1,1,CH,EQ,C'1'),BUILD=(1:2,4) 
  OUTFIL FNAMES=NOMATCH2,INCLUDE=(1,1,CH,EQ,C'2'),BUILD=(1:2,4) 
/*
  • JOINKEYS指定比较两个文件的字段.

  • REFORMAT FIELDS =?在输出BUILD的第一个位置放置'B'(匹配的记录),'1'(在file1中,但不在file2中)或'2'(在file2中但不在file1中).

  • JOIN UNPAIRED对两个文件进行完全外连接.

输出将是:

MATCH File1000
1003NOMATCH1 File1001
1005NOMATCH2 File1002


使用ICETOOL也可以实现相同的功能.