首页 > 代码库 > JCL笔记
JCL笔记
本文转自《http://leowzy.iteye.com/blog/888931》
-----------------------------------------------------------------------------
整理笔记 很TM烦,不过效果确实蛮好的,所以。。。硬着头皮,接着写吧。
笔记内容:
作业控制语言JCL(类似UNIX下的shell语言)是批处理作业的用户与操作系统的接口 。
作业(作业步1,作业步2,……,作业步n),作业步1……作业步n是顺序执行的 。
作业由以下三步组成:
(1)、编译 (2)、连接编辑(3)、执行
-
JCL语句的分类:
[基 本语句] (必须以“//”开头)
1、作业语句(JOB):标识一个作业的开始,提供必要的运行参数。
2、执行语句(EXEC):标识一个作业步的开始,定义本作业步所要执行的程序或过程。
3、数据定义语句(DD):描述应用程序所需要的数据文件。
[附加语句]
4、/*:流内数据结束或调用JES控制语句。
5、//*:注释语句,注释内容写在第4列到第80列。
6、PROC:流内过程或编目过程的起始标记。
7、PEND:标志一个流内过程的结束。
8、Command:在输入流中 写入操作命令。
JCL语法规则:
[JCL字符集]
26个大写字母+10个数字+10个特殊字符+6个通配符+EBCDIC可打印字符集(X‘40’~X’FE‘)
其中,特殊字符的相关说明如下:
",": 分隔参数、分隔子参数JOB (2000,100,300),GOND=(9,LT)
"=":分隔关键字参数与它的值CLASS=A
"(b)":括起子参数列表或PDS、PDSE的成员名
"&" :标志一个符号参数&LIB
"&&": 标志一个临时数据集命&&TEMPDS标志一个流内或系统输出数据集命&&PAYOUT
"." : 分隔受限数据集名字的各个部分ST018.PDS.DATA
分隔一些特定参数与子参数的各部分nodename.userid
"*" : 提及一条先前的语句 OUTPUT=*.name在特定语句内标志特定功能//ddname DD*
" ‘ ":括起含有特殊字符的参数值william‘ lin应该转换为‘william‘‘ lin‘
"(空格)":划分域
[JCL语句格式规范]
语句80列: 标识符区(//或/*或//*)+名字区(1~8列)+空格+操作符区(JOB ....)+空格+参数区+说明区
需要注意的地方:
1、为免混淆,仅当参数出现时才能写说明信息.
2、参数区的书写详见下面的[参数规则]
3、JCL只允许参数区和说明区有续行。当需要续行时,在当前行的第71列前必须将某个参数或某个
子参数以及参数后的逗号写完整,且下一行第1、2列为“//”,第3列为空格,续行的内容只能从
第4~16列开始(16列后开始的话将被认为是注释语句的续行 )。=_= !!
//DATA DD DSN=SYS1。FORTLIB,
// DISP=OLD
4、注意用空格来划分区域!
[JCL参数规则]
位置参数:与其他参数保持相对位置的参数
关键字参数:由一个关键字和等号后面的数据组成
1、位置参数和关键字参数之间用逗号隔开,不允许有空格,切记切记。
2、关键字参数必须写在同一级别的关键字参数之后。
3、缺省(不等于没有)某个位置参数或某个子参数时,必须用逗号指明所在位置
若缺省的是最后一个位置参数,则逗号可以省略
//EXP JOB (2000,,9),CLASS=A
//SYSTEM JOB ,SYSTEM,CLASS=S,MSGLEVEL=(0,0)
4、如果没有任何位置参数,则不必书写任何内容表示//EXP JOB class="A"
5、含有特殊字符的参数一般要用“‘ ”将其括起来。其中,‘用‘‘表示,&用&&表示....
(这个有点复杂,有待进一步研究)
6、位置参数和关键字参数最多只能有两级子参数。
[JCL语法实例]
//EXPJOB JOB,‘USERNAME‘,MSGLEVEL=(1,1),EXAMPLE#作业语句,EXAMPLE为注释
//MSGGLASS=Q,CLASS=A#作业语句续行
//******************#注释语句
//*IT‘S AN EXAMPLE*
//******************
//STEP1 EXEC PGM=IEFBR14#执行语句
//DD1 DD DSN=MJSN.TEAM01.ONE,DISP=(,GATLG),#DD语句
//SPACE=(TRK,(5,2)),UNIT=SYSDA#DD语句续行
//DD1 DD DSN=MJSN.TEAM01.TWO,DISP=(,KEEP),#DD语句
//SPACE=(TRK,(1,1)),UNIT=SYSDA#DD语句续行
PS: 注释有两种方法,记住了哦^_^
JOB语句:
语句格式://作业名 JOB 位置参数[,关键字参数][,关键字参数]...[注释说明]
作业名建议为USERID+数字或字符
[位置参数]
1、记帐信息 :提供用户使用系统的合法性、机时及纸张收费管理等。
格式:([account-number][,accounting-information]...)
account-number:用户帐号
accounting-information:附加记帐信息,如部门..等
//ST018A JOB (ST018,‘6/7/2006‘,PGMBIN)
//ST018B JOB ST018
2、程序员名 :表示作业的所有者(owner)信息,长度不得超过20个字符
//ST018A JOB 2006,W.I.L.L.I.A.M
//ST018B JOB 2006,WILLIAM
//ST018C JOB 2006,‘WILLIAM‘‘LIN‘
例子:
全部位置参数: //ST018EXP JOB (20006,60),WILLIAM,CLASS=S,....
缺省记帐信息: //ST018EXP JOB ,WILLIAM,CLASS=S,....
不带位置参数: //ST018EXP JOB class="S",....
[关键字参数]
1、ADDRSPC :指明作业 所需之存储类型。有两个子参数:VIRT(缺省)、REAL。前者表示作业请求页式存储,后者表示作业请求实存存储空间。
2、BYTES : 指明打印作业的系统输出数据集的最大千字节数,并指出当超过所为最大字节数时系统对作业的处理方式。处理方式包括:CANCEL(取消且不转储)、 DUMP(取消且转储)、WARNING(继续作业且发出警告信息)。类似BYTES(千数)的关键字参数有:CARDS(卡数)、LINES(行数)、 PAGES(页数)。
3、CLASS :规定作业的类别,JCL可选的作业类别有36个,用字母A~Z、数字0~9表示。相同类别处于同一输入队列等待执行。
4、MSGCLASS :对作业日志(job log:与作业相关信息的记录)设置输出类别。类别种类和CLASS中的类别一样。
5、MSGLEVEL :控制JCL作业输出清单的内容。格式:MSGLEVEL={[statements][,messages]}。其中,statements、messages的说明如下:
statements=0:仅打印出作业的JOB语句
=1:打印出作业中包括过程语句在内的所有JCL语句
=2: 打印出输入流中的所有控制语句
messages=0:仅当作业 异常终止时,才打印出有关JCL、JES、操作员及SMS的处理信息
=1:无论作业是否异常终止,都打印出有关JCL、JES操作员及SMS的处理信息。
例如://EXMP JOB ,MSGLEVEL=(2,1)
//EXMP JOB ,JSGLEVEL=0
//EXMP JOB ,MSGLEVEL=(,0)
6、NOTIFY :请求系统在后台作业处理完毕时给指定用户发信息。NOTIFY={USERID}
7、PRTY :为输入队列设置优先级。PRTY=priority。priority的取值范围:0~15(JES2)、0~14(JES3)。对于同一优先级的作业,采用FIFO的方法执行。
8、REGION :指定作业所需的实存或虚存空间的大小
REGION={valueK}
={valueM}
例子://ACCT1 JOB A23,SMITH,REGION=100K
//ACCT2 JOB A23,REGION=2M
9、TIME :指定作业占用处理器的最长时间。当作业时间超过限制后,系统将终止该作业。
TIME={([minutes][,seconds])}
={1440}#无限制
={NOLIMIT}#无限制
={MAXIMUM}#运行时间为357912分钟
10、TYPRUN :请求特殊的作业 处理
TYPRUN={COPY}#仅支持JES2;请求JES2将输入作业流直接拷贝的输出数据集进行处理。
={HOLD} #请求系统在执行前将其挂起,等待某特定事件发生。
={JCLHOLD}#请求JES2在JCL执行前挂起,直到操作员将其释放。
={SCAN}#只对作业的JCL进行语法检查,不执行也不分配设备。
11、(待续……)
EXEC语句:
//[作业名] EXEC 位置参数[,关键字参数]...[符号参数=值]...[注释]
[位置参数]
有两个位置参数,只能二选其一。
1、PGM :指明所要执行的程序名。该程序必须是PDS的成员或系统库、私有库及临时库的PDSE的成员。调用方法有直接调用和间接调用。
PGM={program-name}
={*.stepname.ddname}
={*.stepname.procstepname.ddname}
program-name:指明要执行程序的成员名或别名,程序名由1~8个字母或通配符开头的字符数字构
成。
*.stepname.ddname:表示要执行的程序名由本作业步前名为“ stepname” 的作业步内名为
”ddname”的DD语句的DSN参数决定。
*.stepname.procstepname.ddname:表示要执行的程序名由本作业步前名为“stepname”的作业步
里所调用过程名为“procstepname”的过程步中相应名为“ddname”DD语句的DSN参数决定。
2、PROC:指明作业步所要运行的过程名。格式如下:
{RPOC=procedure-name}
{procedure-name}
//SP EXEC PROC=PAYWRKS
//SP EXEC OPERATE
procedure-name:调用的过程名可以是:编目过程的成员名或别名;由PROC语句定义的流内过程的过程名,该流内过程必须在本作业内且本作业步前定义。
[关键字参数]
P.S 作用范围仅限于本作业步,总的书写格式:关键字参数[.过程步名]=值
1、ACCT:指明作业步所需懂的一个或多个记帐信息子参数.格式:ACCT[.过程步名]=(记帐信息)
//STP3 EXEC PROC-=LOOKUP,ACCT=(‘/83468‘)
2、ADDRSPC:指明作业步所需之存贮类型,方法同JOB中的ADDRSPC参数.
3、REGION:同JOB语句中的REGION
4、TIME:同JOB中的TIME
5、COND:用于对先前作业步执行的返回码(return code)进行测试,以决定是否执行本作业步.当条件满足时(有一个满足即可)系统不执行本作业步,即跳过本作业步.格式如下:
COND[.过程步名]=(code,operator)
=((code,operator[,作业步名][,过程步名])
[,(code,operator[,作业步名][,过程步名])],...[,EVEN])
[,ONLY]
COND=EVEN
COND=ONLY
说明:最多可测试8个返回码,EVEN(ONLY)也算一个返回码的名额.code0用来与返回码的比较,取值范围0~4095。operator表示比较类型,GT(大于)、GE(大于等于)、EQ(等于)、NE(不等于)、LT(小于)、LE(小于等于)。EVEN表示无论先前作业步是否异常终止,本作业步都要执行(测试先哦)。ONLY表示只有先前作业步异常终止时,本作业步才执行(还要测试滴)。
//STEP2 EXEC PGM=DUMPINT,COND=((16,GE),(90,LE,STEP1),ONLY)
//STP4 EXEC PROC=BILLING,COND.PAID=((20,LT),EVEN),
//COND.LATE=(60,GT,FIND),
//COND.BILL=((20,GE),(30,LT,CHGE))
6、PARM:用于向本作业步执行的程序传递变量信息。该程序必须有相应的指令接受这些信息。
PARM[.过程步名]=子参数
=(子参数,子参数)
=(‘子参数‘,子参数)
=‘子参数,子参数‘
//RUN1 EXEC PGM=APG22,PARM=‘P1,123,P2=5‘#将参数P1、123、P2=5传递给APG22
//STP6 EXEC PROC=ASFCLGP,PARM.LKED=(MAP,LET)
#将参数MAP、LET传递到过程ASFCLG中名为LKED的过程步
DD语句:
//[dd名 ] DD [位置参数][,关键字参数]...[注释]
[过程步名.dd名]
//[dd名 ]DD
[过程步名.dd名]
dd名不能与系统定义的dd名重复
[位置参数]
此三者取其一
1、*:开始一个流内数据。数据记录跟在DD语句之后,其第一、第二列不能是“//”或“/*”(因为这两个符号标记了流内数据记录的结束)。倘若数据记录需要以“//”开始,就必须以DATA参数代替*。
//INPUT1 DD *
.
.
data
.
//INPUT2 DD .....
//STEP2EXEC PROC=FRESH
//SETUP.WORK DD UNIT=3400-6,LABEL=(,NSL)
//SETUP.INPUT1 DD *
.
.
data
/*
//PRINT.FRM DD UNIT=180
//PRINT.INP DD *
.
.
data
/*
注意数据集所对应的过程步名.
2、DATA:用于一个流内数据的开始,该流内数据可以含有以“//”开头的语句。数据记录以“/*”来结束。用法与“*”参数基本类似。
3、DUMMY:用于标明(1)没有设备或外存空间分配给该数据集(2)对该数据集不进行状态处理(3)对BSAM或QSAM来说,不对该数据集作输入输出操作。
//OUTDD1 DD DUMMY,DSNAME=X.X.Z,UNIT=3380,SPACE=(TRK,(10,2)),DISP=(,CATLG)
该DD语句定义了一个空数据集.该语句出DUMMY以外的参数将接受系统语法检查但并不起作用.
[关键字参数]
总的可分为两类,一类是与设备相关的,另一类是与数据集或数据相关。
1、UNIT:用于请求物理设备
{UNIT=([三位设备地址][,设备数][,DEFER])}
[/三位设备地址][,P]
[/四位设备地址][,]
[设备类型]
[设备组名]
{UNIT=AFF=DD名}
设备地址:通过设备地址指定设备.
设备类型:通过设备类型指定设备,这个名称通常是数字.比如通过3480、3422指定磁带机,3340、3375、3380、3390指定磁盘机。
设备组名:通过设备组名请求一台或一组设备.组名有1~8个字母符号构成,常见的有SYSDA、DASD、TAPE、CART等。如果需要直接访问的存储设备时,参数可以设置为:UNIT=DASD。
设备数:所需设备数量,1~59取值.
例子:
//STEP2 EXEC PGM=POINT
//DDX DD DSNAME=EST,DISP=MOD,
// VOLUME=SER=USER01,
// UNIT=(3390,2)
//DDY DD DSNAME=ERAS,DISP=OLD,UNIT=3390
//DDZ DD DSNAME=RECK,DISP=OLD,
// VOLUME=SER=USER01,UNIT=AFF=DDX
//DD3 DD DSNAME=COLLECT,
// DISP=OLD,
// VOLUME=SER=1095,
// UNIT=(3490,,DEFER)
DDX请求分配两个3390设备,DDZ申请分配与DDX相同的
两个设备,DDY申请分配一个3480设备。DD3所请求的磁带卷只到数据集
被打开时才会装载。
2、VOLUME:指定所引用(或者是新建)数据集所在的卷或卷组。在使用这个参数时,用户可以指定一个特定的卷、一组卷、具有特定序列号的卷或另外一个数据集所使用的卷。对于一个跨越多个卷的数据集来说,这个参数还可以用来指定首先被处理的卷。对于一个新建的数据集来说,可以通过不指定VOLUME参数或在VOLUME参数中不指定SER和REF子参数的方法在任何一个卷或卷组上创建该数据集,我们称这种方法为非特定卷。
{VOLUME}=([PRIVATE][,RETAIN][,卷顺序号][,卷数])
VOL =[,][, ]
[SER=序列号]
[SER=(序列号[,序列号]...) ]
[,] [REF=数据集名]
[REF=*.DD名]
[REF=*.作业步名.DD名]
[REF=*.作业步名.过程作业步名. DD名]
PRIVATE:申请一个私有的卷。这里的私有卷是指:
(1)除非使用VOLUME=SER子参数明确地请求这个卷,否则系统不会在这个卷上分配输出数据集。
(2)对于一个磁带卷来说,除非指定了RETAIN子参数或在DISP参数中指定PASS,否则这个磁带卷将会在数据集关闭后被卸载。
(3)对于一个可卸载的直接访问卷来说,这个卷将在数据集关闭后被卸载。
RETAIN:对于一个私有磁带卷来说,指定RETAIN子参数表示在数据集关闭后或在作业步结束后,这个卷不会被卸载;对于一个公共磁带卷来说,如果这个卷在作业中被卸载,它将保留在相应的设备上。
卷顺序号:用来在一个多卷的数据集中确定开始处理的卷。卷顺序号为1~255的十进制数,第一个
卷的顺序号为1,卷的顺序号必须小于等于数据集所占用的实际卷数,否则作业将会失败。如果不指定卷顺序号,则系统从1开始处理。对于一个新数据集系统将忽略所指定的卷顺序号。
卷数:用来确定一个输出数据集所申请的卷的最大数量。卷数为1~255的一个十进制数,在一个作业步中所有的DD语句中的卷数总和不能超过4095。
SER :通过卷的序列号用来确定数据集占用或将占用那些卷。一个卷的序列号为1~6个字符,可以包含字母、数字和$、#、@等特殊字符。不足6位的序列号将被空格填满。在一条DD语句中最多可以指定255个卷序列号。不要在一个SER子参数中指定重复的序列号,无论是磁带卷还是磁盘卷,每个卷都应该有唯一的卷序列号。不要将序列号指定为SCRTCH、PRIVAT或Lnnnnn(L后有五个数字),这些名字已经被用在请求操作员装载卷的消息中;不要将序列号指定为MIGRAT,这个名字被DFHSM Data FacilityHierarchical Storage Manager)用来做数据集的移植。
REF:用来表示系统将从其它的数据集或前面的DD语句中获得卷序列号的信息。
例子:
//OUTDD DD DSNAME=TEST.TWO,DISP=(NEW,CATLG),
//VOLUME=(,,,3,SER=(333001,333002,333003)),
//SPACE=(TRK,(9,10)),UNIT=(3330,P)
//NEXT DD DSNAME=TEST.TWO,DISP=(OLD,DELETE)
//
//STEP1 EXEC PGM=....
//DD1 DD DSN=OLD.SMS.DATASET,DISP=SHR
//DD2 DD DSN=FIRST,DISP=(NEW,CATLG,DELETE),VOL=REF=*.STEP1.DD1
3、SPACE:为新建数据集分配磁盘空间,对于磁带卷不起作用。请求空间分配一般有两种方法:一是告知系统所需空间大小,由系统来分配合适的空间;二是请求系统分配某个特定的空间,如:从某个特定磁道到另一个特定磁道。
当用第一种方法时,用户告诉系统所要分配空间的存贮单位及存贮空间单位的数量。存贮单位可以是磁道(TRK)、柱面(CYL)、块长及记录长。不同类型的磁盘设备其磁道、柱面容量也不同,所以为数据集分配空间时,要清楚用户所用的设备类型及磁道、柱面的容量。
格式(由系统分配空间):
SPACE=({TRK,}(初次分配数量[,再次分配数量][,目录空间])[,RLSE][,CONTIG][,ROUND])
({CYL,}[,][,索引][,][,MXIG ])
({块长度, }[,ALX ]
({记录长度,}[, ]
Notes:SPACE的子参数均为位置参数
说明:
TRK:表示系统以磁道为单位分配空间。
CYL:表示系统以柱面为单位分配空间。
块长度:用来指定数据的平均块长度(字节),块长度是0~65535的一个十进制数,这里指定的块长度用来作为空间分配的单位。
记录长度:在SMS环境下用来指定数据的平均记录长度(字节),记录长度是0~65535的一个十进制数。这里指定的字节数用来作为空间分配的单位。当记录长为0时,将不对存储空间进行分配。
初次分配数量:初次为数据集分配的空间的大小,单位为磁道、柱面等。如果使用TRK或CYL作为单位为一个分区数据集分配空间,则初次分配的空间包含了目录空间;如果使用块长度或记录长度作为单位为一个分区数据集分配空间,则初次分配的空间不包含目录空间,系统另外分配目录空间。所要求的卷必须有足够的空间用于初次分配,否则作业将失败。
再次分配数量:当初始量指定的空间大小不能满足需要时,系统会根据追加量为用户分配附加的存储空间。这种分配是动态分配,所以空间可以不连续,最多可以追加15次。
目录空间:用于指定分区数据集目录区的空间大小,以256字节为块单位进行分配,每个块长可以包含5个成员名。索引:对于一个索引顺序数据集的索引来说,用来指定索引区所需的空间,以磁道或柱面为单位,指定的磁道数应该等于一个或多个柱面。
RLSE:表示在数据集关闭时,那些分配给数据集但没有被使用的空间将会被释放。前提条件是数据集必须为了输出被打开并且最后一个操作为写操作。
CONTIG:指定分配给数据集的空间必须是连续的,这个子参数仅仅影响初次分配。
ROUND:当存储单位为“块长度”时,表示分配的空间必须等于整数柱面,其它情况下忽略这个子参数。
MXIG:要求为数据集分配的空间必须1.是卷上最大的连续空间;2.大于或等于初次分配的空间大小。这个子参数仅仅影响初次分配。
ALX:作业在分配空间时将获得卷上最多5个最大的连续空间,并且每一个空间都应大于或等于初次分配的空间大小。这个子参数仅仅影响初次分配。
格式(申请特定的磁道):
SPACE=(ABSTR,(初次分配数量,地址[,目录空间]))
[,索引]
格式:仅请求目录空间:
SPACE=(,(,,目录空间))
说明(申请特定磁道):
ABSTR:表示将在卷上特定的位置为数据集分配空间。初次分配数量:指定为数据集分配的磁道数,要求卷上必须有足够的空间。地址:指定分配的第一个磁道的磁道号,第一个柱面上第一个磁道的磁道号为0。
例子:
//DD2 DD DSNAME=PDS12,DISP=(,KEEP),
// UNIT=3350,
// VOLUME=SER=25143,
// SPACE=(CYL,(10,1,10),,CONTIG)
在DD语句中定义了一个新的分区数据集,系统将为这个数据集分配10个柱面,其中创建10个256字节的记录作为目录。由于指定了CONTIG子参数,系统将在卷上为数据集分配10个连续的柱面.
//REQUEST1 DD
// DSNAME=EXM,DISP=NEW,
// UNIT=3330,VOLUME=SER=606674,
// SPACE=(1024,75),DCB=KEYLEN=8
在本例的DD语句中根据块长分配空间,数据的平均块长为1024字节,需要申请75个数据块,每一个数据块前都需要有一个8个字节长的键,系统将会根据UNIT参数指定的设备计算需要多少个磁道。
下面我们以3380磁盘为例,来看看space参数的使用情况,计算我们实际分配给数据集的空间大小:例1:Space=(CYL,3)3*15*47476=2136420字节
例2:Space=(TRK,3)3*47476=142428字节
例3:Space=(800,300)800*300=240000字节
4、DISP:向系统描述数据集的状态,并且可以设定系统在作业步或作业结束时如何处理相应的数据集。
格式:
{DISP=状态}
{DISP=([状态][,正常结束参数][,非正常结束参数])}
DISP= ([NEW] [,DELETE ] [,DELETE ])
[OLD][,KEEP ][,KEEP ]
[SHR][,PASS ][,CATLG ]
[MOD] [,CATLG ][,UNCATLG]
[, ][,UNCATLG]
[,]
Notes:所有的子参数均为位置参数。
状态参数说明:
NEW—表示在当前作业步中创建一个新的数据集。
OLD—表示该数据集在当前作业步运行之前已经存在,并且当前作业步将以独占的方式使用这个数据集。
SHR—表示该数据集在当前作业步运行之前已经存在,并且当前作业步将以共享的方式使用这个数据集,也就是说其它的作业也可以同时使用这个数据集。这个参数值也可以写成SHARE。
MOD—表示下列两种情况之一:1.数据集已经存在,记录将被添加到数据集的结尾,这个数据集必须是顺序的;2.一个新的数据集将被创建,在任何一种情况下数据集都将以独占的方式被使用
正常结束参数说明:
DELETE—表示在作业步正常结束后,该数据集将不再需要而被删除,所占用的空间将会被释放。KEEP—表示在作业步正常结束后,该数据集仍将继续保留在相应的卷上,它是缺省值。
PASS—表示该数据集将会被保留传递到同一作业的后续作业步中被使用。
CATLG—在作业步正常结束后,系统将对数据集进行编目,在系统编目或用户编目中设置相应的入口指针指向该数据集。
UNCATLG—在作业步正常结束后,系统解除对数据集的编目,在系统编目或用户编目中删除相应的入口指针和索引。
•DISP参数缺省:
•NO DISP : DISP=(NEW,DELETE,DELETE)
•DISP=OLD : DISP=(OLD,KEEP,KEEP)
•DISP=(,CATLG): DISP=(NEW,CATLG,CATLG)
•DISP=NEW : DISP=(NEW,DELETE,DELETE)
•DISP=SHR : DISP=(SHR,KEEP,KEEP)
•DISP=MOD : DISP=(MOD,KEEP,KEEP)
例子:
DISP//IXSAMP06 JOB ‘MZ’,’GZ’,…
//…
//STEP0X EXEC PGM=PROGRAM1,PARM=(…,…)
//DS1 DD DSN=TE02.DS1,DISP=NEW
这里把DISP=NEW相当于DISP=(NEW,DELETE,DELETE)。也就是说当作业步第一次访问这个数据集的时候,系统会试图创建这个数据集,如果作业步正常结束或者不正常结束则删除该数据集
5、DCB:数据控制块参数,用于描述数据集的属性特征,包括记录长度,格式和记录块大小等,新建数据集时必须设置该参数。
格式:
[ DCB=(子参数[,子参数]...)]
[ DCB= ( {数据集名}[,子参数]...)]
[( {*.DD语句名})]
[( {*.作业步名.DD语句名})]
[( {*.作业步名.过程作业步名.DD语句名})]
子参数介绍:
RECFM:用于指定记录格式。
RECFM=FB(定长组块记录)F (定长不组块记录)VB(变长组块记录)V (变长不组块记录)
LRECL:用于指定数据集的记录长度。LRECL=bytes对于定长记录,LRECL的值为实际记录的长度;对于变长记录,LRECL的值为最大记录长加上4个字节的控制信息。
BLKSIZE:指定数据集记录块的大小。BLKSIZE=bytes最大的块长为32K,对于定长组块记录,BLKSIZE的值必须是LRECL的整数倍。对于变长组块记录,情况复杂一些,要多8个字节的控制信息。
例1//DD1 DD DSNAME=ALP,DISP=(,KEEP),// VOLUME=SER=44321, UNIT=3400-6,// DCB=(RECFM=FB,LRECL=240,BLKSIZE=960)DD语句DD1中定义了一个名为ALP的新的数据集。在DCB参数中包含了用以完成数据控制块的必要信息。
例:
//DD4 DD DSNAME=JST,
// DISP=(NEW,KEEP),UNIT=SYSDA,
// SPACE=(CYL,(12,2)),DCB=(A.B.C,KEYLEN=8)
DD语句DD4中定义了一个名为JST的新的数据集,并且要求系统参照一个已编目的数据集A.B.C的DCB信息来确定本语句中的DCB参数的值,通过指定子参数KEYLEN来将相应的定义覆盖。
6、SYSOUT:通过SYSOUT参数可以将相应的数据集标志为一个系统输出数据集,同时SYSOUT参数还可以完成以下的定义:(1)将这个系统输出数据集与一个输出类关联起来;(2)不通过JES而是要求一个外部的书写器程序来处理这个系统输出数据集;(3)指定这个数据集被打印输出的格式;(4)引用JES2的/*OUTPUT语句。
系统输出数据集根据下面的输出定义顺序被处理:(1)在SYSOUT DD语句中指定的选项;(2)参考JCL的OUTPUT语句中指定的选项;(3)参考JES2的/*OUTPUT语句中指定的选项或(4)JES3的//*FORMAT语句中指定的选项;(5)相关的输出类的缺省值。
格式:
SYSOUT= { 输出类}
{ * }
{ ([输出类] [,书写器名] [,格式名]) }
[,INTRDR ] [,代码名]
SYSOUT=(,)
说明:
输出类:为数据集指定的输出类,输出类为一个字符:A~Z或0~9。
*—表示输出类与在JOB语句中MSGCLASS参数的定义相同。
(,)—指定输出类为空值。当引用JCL的OUTPUT语句中CLASS参数的定义时必须指定输出类为空值
书写器名:确定一个系统书写器程序的名字(1~8个字符)。一个外部书写器程序是系统中一个用来处理输出的已启动的任务,每一个外部书写器程序有一个用户标识符与其相关联。通过在DD语句中指定外部书写器的名字来使用该书写器程序处理输出。(晕。。。。。)
NTRDR:通知JES将这个系统输出数据集作为输入作业流送到内部读卡机。
格式名:确定打印输出的格式,格式名为1~4个字符,可以为字母、数字或特殊字符($、#、@)。
代码名:用来确定JES2获得处理属性的JES2 /*OUTPUT语句,代码名必须与JES2的/*OUTPUT语句中的CODE参数相同。代码名仅仅被JES2系统支持,当作业或作业步中包含了一个缺省的JCL OUTPUT语句时不要使用代码名。
例:
//DD5 DD SYSOUT=(F, ,2PRT)
在本例的DD语句中指定JES将系统输出数据集写到处理F类输出的设备上,数据集将会按照名为2PRT的输出格式被打印。
7、SYSIN:通常,我们使用SYSIN DD语句作为一个内部流数据集的开始。内部流数据集以DD *或DD DATA语句开头,这样的DD语句可以有任何一个有效的名字,包括SYSIN。如果在内部流数据之前省略这样的DD语句,系统会自动提供一个名为SYSIN的DD *语句。
格式:
//SYSIN DD 参数[,参数]... [说明]
说明:第一个参数为*或DATA,用以指出后面紧跟的是内部流数据。这条语句必须且只能够位于内部流数据前。
8、DSNAME:指定一个数据集的名字,该数据集可以是已经存在,或者是新建的。
格式:{DSNAME}=名字
{DSN}
如果是新建的数据集的话,一般后面要跟相关的关键字参数:DISP,SPACE,UNIT,VOLUME,DCB。如果是已经存在的数据集,则后面一般跟DISP。
9、JOBCAT:
通过DD语句JOBCAT可以为作业定义一个私有的VSAM用户编目或完整的编目功能。系统可以在搜索主编目或搜索与数据集名的第一部分相关联的私有编目前先搜索本语句中定义的私有编目。
当作业中引用了一个SMS数据集时不要使用JOBCAT语句,因为SMS仅仅访问那些在系统编目中进行编目的SMS数据集。
格式:
//JOBCAT DD DISP={OLD},
// DSNAME=私有编目名[,参数]... [说明]
{SHR}
说明:
不要指定任何UNIT和VOLUME参数,系统将会从主编目中获取私有编目的位置。
可以通过在JOBCAT语句后立即跟有省略了语句名的DD语句的方法为作业指定多个这样的私有编目。应当将JOBCAT语句放置在JOB语句之后,并且位于第一个EXEC语句之前。
如果作业中包含了JOBLIB语句,应当放置在JOBCAT语句之前。
//EXAMPLE JOB WILLIAMS,MSGLEVEL=1
//JOBLIB DD DSNAME=USER.LIB,DISP=SHR
//JOBCAT DD DSNAME=LYLE,DISP=SHR
//STEP1 EXEC PGM=SCAN
在这个例子中,JOBCAT语句指定了一个私有编目LYLE,并且JOBCAT语句位于JOBLIB语句之后。
10、JOBLIB:通过JOBLIB DD语句用户可以创建一个私有库或为作业指定一个私有库。系统将会首先搜索所指定的私有库去查找那些在EXEC语句的PGM参数中使用的程序,只有在私有库中没发现相匹配的程序时系统才会去搜索系统库。
一个私有库实际上是一个位于一个直接访问设备上的分区数据集(PDS)或分区数据集扩展(PDSE),其中的每一个成员都是一个用户的可执行程序。
格式://JOBLIB DD 参数[,参数]... [参数]
说明:
定义已编目的库:指定DSNAME参数;指定DISP参数,其中的状态子参数必须为OLD或SHR;不需要指定VOLUME或UNIT参数。
定义未编目的库:指定DSNAME参数;指定DISP参数,参数值必须为DISP=(OLD,PASS)或DISP=(SHR,PASS);其中SHR表示这个数据集是已经存在的并允许其它作业使用这个库;指定UNIT参数;指定VOLUME参数。
创建一个库:指定DSNAME参数,作为库的名字;指定UNIT参数,注意一个库必须建立在一个直接访问设备上;指定VOLUME参数,非特定卷的情况例外;指定SPACE参数,为整个库分配足够的空间,并为PDS的目录分配空间;指定DISP参数,其中的状态子参数必须为NEW。
向库中添加成员:DSNAME参数包含相应的成员名,例如,DSNAME=LIBRARY(PROGRAM);将DISP参数中的状态子参数指定为MOD,如果在创建库时已经编目则不需要其它子参数,否则指定为PASS或CATLG;不要指定SPACE参数。其它参数:如果在数据集标签中不包含数据控制块信息则需要指定相应的DCB参数,但不要指定FREE=CLOSE。
例1
//PAYROLL JOB JONES,CLASS=C
//JOBLIB DD DSNAME=PRIVATE.LIB4,
// DISP=(OLD,PASS)
//STEP1 EXEC PGM=SCAN
//STEP2 EXEC PGM=UPDATE
//DD1 DD DSNAME=*.JOBLIB,
// DISP=(OLD,PASS)
在本例中JOBLIB DD语句中所指定的私有库已经被编目,所以无需指定UNIT和VOLUME参数。系统首先搜索私有库PRIVATE.LIB4去查找程序SCAN和UPDATE,其次才查找系统库SYS1.LINKLIB。在DD1语句中引用了JOBLIB DD语句中指定的私有库。
例2
//PAYROLL JOB FOWLER,CLASS=L
//JOBLIB DD DSNAME=PRIV.DEPT58,
// DISP=(OLD,PASS),
// UNIT=3350,VOLUME=SER=D58PVL
//STEP1 EXEC PGM=DAY
//STEP2 EXEC PGM=BENEFITS
//DD1 DD DSNAME=*.JOBLIB,
// VOLUME=REF=*.JOBLIB,DISP=(OLD,PASS)
因为在本例中JOBLIB DD语句中所指定的私有库没有被编目,所以必须指定UNIT和VOLUME参数。系统首先搜索私有库PRIV.DEPT58去查找程序DAY和BENEFITS,其次才查找系统库SYS1.LINKLIB。在DD1语句中引用了JOBLIB DD语句中指定的私有库。
例4
//PAYROLL JOB BIRDSALL,TIME=1440
//JOBLIB DD DSNAME=KRG.LIB12,
// DISP=(OLD,PASS)
// DD DSNAME=GROUP31.TEST,
// DISP=(OLD,PASS)
// DD DSNAME=PGMSLIB,UNIT=3350,
// DISP=(OLD,PASS),VOLUME=SER=34568
通过三个DD语句为作业定义了三个相连接的私有库,系统将按照下面的顺序查找每一个程序:KRG.LIB12;GROUP31.TEST;PGMSLIB;SYS1.LINKLIB。
11、STEPCAT:通过DD语句STEPCAT可以为作业步定义一个私有的VSAM用户编目或完整的编目功能。系统可以在搜索主编目或搜索与数据集名的第一部分相关联的私有编目前先搜索本语句中定义的私有编目。
当作业步中引用了一个SMS数据集时不要使用STEPCAT语句,因为SMS仅仅访问那些在系统编目中进行编目的SMS数据集。
格式
//STEPCAT DD DISP={OLD},
// DSNAME=私有编目名[,参数]... [说明]
{SHR}
说明:
不要指定任何UNIT和VOLUME参数,系统将会从主编目中获取私有编目的位置。可以通过在STEPCAT语句后立即跟有省略了语句名的DD语句的方法为作业指定多个这样的私有编目。
通过下面的语句可以在一个特定的作业步中用主编目覆盖JOBCAT中定义的私有编目://STEPCAT DD DISP=OLD,DSNAME=主编目名。在一个作业步中可以将STEPCAT语句放在DD语句中的任何一个位置。
//STEP2 EXEC PROC=SNZ12
//STEPCAT DD
//DSNAME=BETTGER,DISP=SHR
STEPCAT语句为这个作业步定义了一个私有编目BETTGER。
12、STEPLIB:STEPLIB语句的作用与JOBLIB相似,主要区别在于作用的范围分别是作业步和作业。同一个作业中后续作业步可以引用在STEPLIB DD语句中定义的私有库,同样,可以将一个STEPLIB DD语句放在内部流或编目过程中,但不能将JOBLIB DD语句放在内部流或编目过程中。
格式:
//STEPLIB DD 参数[,参数]... [说明]
13、IF-THEN-ELSE-ENDIF:条件语句
//IXSAMP23 JOB ‘AC’,’GZ’,CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
//…
//STEP01 EXEC PGM=PROGRAM1, PARM=(10,’2008-01-29’)
//…
//TESTSTEP IF (STEP01.RC = 8) THEN
//STEP0X EXEC PGM=PROGRAMX
//…
// ELSE
//STEP0Y EXEC PGM=PROGRAMY
//…
// ENDIF
如果作业步STEP01的执行返回码为8,那么条件为真,执行作业步STEP0X,否则执行作业步STEP0Y
小结:
TNND,这个JCL真恶心。本来做这篇笔记的初衷是记录些重点,怎奈JCL貌似都是重点,细节的东东太多了。做到后来的DD语句时,都有点想放弃,郁闷,后来没办法,只好把老师的PDF拷过来。TNND,这哪是笔记啊,都成帮助文档了。
JCL笔记