打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
JCL 1

作业控制语言

3.1  基本概念

   在大型服务器系统中,当用户需要使用计算机完成某项任务时,用户必须准备一个作业流(Job Stream)。作业流中包含一个或多个作业(Job)。作业是用户在完成该任务时要求计算机所做工作的集合。
   与COBOL等一般的编程语言不同,作业控制语言JCL(Job Control Language)是用户与操作系统的接口。用户通过JCL的相应语句来与操作系统通讯,获得作业所需的资源等,按自己的意图来控制作业的执行。
JCL由几个语句组成,对于一个作业,JCL为被执行的任务引导操作系统,并说明所需要的全部I/O设备。
在一个作业中,每一次程序的执行称为一个作业步,一个作业可包含几个作业步。一般的,一个作业由以下相对独立的三步组成:
(1)        编译:把源程序语句(源模块)转换成目标模块;
(2)        链接编辑:把目标模块同子程序库中的其他程序链接起来得到可执行模块;
(3)        执行:运行可执行模块得到结果。
一个作业中的各步是顺序执行的,因此一个作业步的输出可以作为下一个作业步的输入。
大型服务器系统中用户的作业可以由一个或多个作业步构成。只有一个作业步的作业叫做单步作业;由多个作业步构成的作业叫做多步作业。不论单步作业还是多步作业都必须包含三个JCL基本语句(JCL Statement)。它们分别是:
(1)        作业语句(JOB):标识一个作业的开始,提供必要的运行参数。
(2)        执行语句(EXEC):标识一个作业步的开始,定义本作业步所要执行的程序或过程。
(3)        数据定义语句(DD):用于描述应用程序所需要的数据文件。
系统规定这三种语句行必须以“//”开头。下面是一个多步作业的例子:
//JOB1    JOB  …      
//STEP1   EXEC …   
//DD1     DD …      作业步1
//STEP2   EXEC …
//INDD1   DD …      作业步2   
//INDD2   DD …     
//
除了上述一些基本概念,有关数据结构和存取方法的概念在JCL的使用中也是非常重要的,由于这一部分已在本书的第二章中详细讨论过,就本章不再重复了。

3.2  JCL语句

3.2.1        JCL语句分类
在大型服务器系统中,作业控制语言被分做两类:JES2和JCL。JES2将在本书的后续章节中讨论。
作业控制语言由九种语句组成,除了上一节中讨论过的三种基本语句外,还有以下六种附加语句:
(1)/* 语句:表示六内数据结束或调用JES控制语句;
(2)//*语句:注释语句,由第4到第80列写出注释内容;
(3)//语句:空语句,用以标记一个作业的结束;
(4)        PROC语句:流内过程(IN-STREAM  PROCEDURE)或编目过程(CATALOGED PROCEDURE)的起始标记。
(5)        PEND语句:标志一个流内过程的结束。
(6)        Command语句:操作员用这个语句在输入流中写入操作命令。
在这九种语句中,JOB、EXEC和DD三种语句对于每个作业来说都是必要的。
下面给出一个单步作业的JCL实例。
//BACKUP JOB   ,’EXAMPLE JOB’
//************************
//*  IT IS A EXAMPLE!   *
//************************
//STEP1    EXEC  PGM=IEBGENER
//STEPLIB  DD    DSN=SYS1.LINKLIB,DISP=SHR
//SYSIN    DD    DUMMY
//SYSPRINT DD    SYSOUT=A
//SYSU1    DD    DSN=PR.MASTER,DISP=OLD
//SYSU2    DD    DSN=PR.MAILY.BACKUP,DISP=(NEW,CATLG),UNIT=TAPE,
//                 DCB=(RECFM=FB,LRECL=200,BLKSIZE=1000)
//
在上述例子中,我们给出了一个名为BACKUP的单步作业,在这个作业中我们通过调用公用程序IEBGENER完成了将库SYS1.LINKLIB中的 PR.MASTER数据集备份到磁带上的工作。通过该例我们可以初步了解JCL中各语句的使用方式,下面我们将详细向大家介绍JCL的语法规则及语句的使用。

3.2.2        JCL的语法规则
与其计算机语言一样,JCL有一套严格的语法规则。但与我们熟知的一些编程语言不同的是,JCL还有其严格的语句格式规范。用户只有严格按照这些规则来编写作业控制程序,系统才能按照其意图正确完成用户的作业,否则系统就会给出错误信息,或产生不可预知的后果。
一、        JCL字符集
(1)        字母(共26个)
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
(2)        数字(共10个)
0        1  2  3  4  5  6  7  8  9
(3)        特殊字符(共10个)
,  .  /  ‘  (  )  *  &  +  -  =
(4)        通配符(共6个)
@  $  #  (也可分别用X’7C’  X’5B’ 和 X’7B’表示)
(5)        EBCDIC 可打印字符集(参见附录)
使用十六进制值表示:X’40’ ~ X’FE’
在JCL语法中会用到一些特殊字符,其作用列表如下表3.2.1:
字符        语法功能
,        分隔参数和子参数
=        分隔关键字参数(见3.2.2节)与它的值,例:CLASS=A
(b )        括起子参数列表或PDS、PDSE的成员名
&        标志一个符号参数(symbolic parameter),例:&LIB
&&        标志一个临时数据集名(temporary data set name)例:&&TEMPDS标志一个流内或系统输出(sysout)数据集名,例:&&PAYOUT
.        分隔受限数据集(qualified data set)名字的各部分,例:A.B.C分隔一些特定参数与子参数的各部分,例:nodename.userid
*        提及一条先前的语句,例:OUTPUT=*.name ,或在特定的语句内,标志特定的功能,例://ddname DD *
‘        括起含有特殊字符的参数值
(空格)        划分域

表  3.2.1

二、        一般语句格式规范
在JCL中,除/*语句外的所有语句均以第一、二列的//符号作为开始标志,系统规定这些语句的长度为80列。这80列在逻辑上被划分为五个区域,分别是标识符区、名字区、操作符区、参数区和说明区,即:
标识符区        名字区        操作符区        参数区        说明区
//        名字        操作符        参数        说明
    标识符区
一般情况下,标识符区的符号为“//”,该符号表明该条语句为JCL语句。标识符区位于每条语句的第一、二列。
在特殊情况下,标识符区的符号将有所变化。如3.2.1中所讨论过的“/*”语句和“//*语句,则分别在标识符区中使用的符号“/*”和“//*”表示。
名字区
名字区指明一个语句,便于系统控制块或其他语句引用它。名字可以由1~8个字母数字或通配符组成,但第一个字符必须是字母或通配符,且必须从第三列开始。名字区后必须跟一个或多个空格,可以选择名字表达出这个JCL语句的作用。下面给出几个正确与错误的名字区的例子:
         正确的                                错误的
   //Z                                         //9Z                                             
   //BACKUP#1                                //TAPEBACKUP
   //#99                                       //TEST*9                                                                                                
   //$EXAM                                   //EXAM(0)
   
    操作符区
操作符区位于名字区之后,规定了语句的类型:JOB、EXEC、DD、PROC、PEND,或操作员命令。名字区后必须跟一个或多个空格。例如:
//EXAMPLE  JOB
//STEP1  EXEC
//INDD1  DD

   参数区
   参数区在操作符区之后,其中包括被逗号分隔的参数,参数由事先规定好的关键字组成,对于这些参数其数值必须是可被代换的变值。参数区没有固定的长度及列的要求。例如:
//EXAMPLE  JOB  2000,CLASS=A
//STEP1  EXEC  PGM=IEYFORT
//PRINT  DD  SYSOUT=A

说明区
说明区位于参数区后,用于对相应语句进行注释说明,它可以是任何需要的说明信息,注释区后必须跟一空格。需要注意的是,仅当参数出现时才能书写说明信息,不然容易与参数混淆。下面是一个说明区的例子:
    //EXAMPLE  JOB  ,CLASS=A  IT IS A COMMENT

JCL只允许在参数区和说明区有续行,当需要续行时,在当前行的第71列前必须将某个参数或某个子参数以及参数后的逗号写完整,且下一行第1、2列为“//”,第3列为空格,续行的内容只能从4~16列开始,如从16列后开始,将被认为是注释语句。下面是一个续行的例子:
//DATA  DD  DSN=SYS1。FORTLIB,
//  DISP=OLD

三、        参数规则
在JCL中,参数区内的参数的类型分为两类:
(1)        位置参数(positional):与其他参数保持相对位置的参数;
(2)        关键字参数(keyword):由一个关键字和等号后面的可变数据组成。
如果在一个语句内既有位置参数又有关键字参数时,所有的关键字参数必须位于位置参数之后。例:
//EXAMPLE  JOB  2000,CLASS=A
                        
                位置参数 关键字参数     
一个位置参数或关键字参数中的可变数字,也可能是一个子参数表。该表中同样可能含有位置和关键字这两种类型的参数,它们同样遵循位置参数和关键字参数的所有规则。当参数有子参数时,子参数必须顺序排列在圆括号括内。例:
//EXAMPLE  JOB  (2000,100,30),COND=(9,LT)
在了解参数类型的概念后,我们总结出参数的书写规则如下:
1.位置参数和关键字参数之间必须用逗号分开,不允许有空格。值得注意的是,在 JCL语句中错写空格,经常导致非常难以查出的错误。
      正确的                                    错误的
//EXAMPLE  JOB  2000,CLASS=A         //EXAMPLE  JOB  2000, CLASS=A
//EXP  JOB  (2000,9),CLASS=A            //EXP  JOB  (2000,9)CLASS=A
2.必须按规定的次序书写参数:所有的关键字参数必须位于位置参数之后,而所有位置参数也必须按规定排列。
      正确的                                    错误的
//EXAMPLE  JOB  2000,CLASS=A           //EXAMPLE  JOB  CLASS=A,2000
3.当缺省某个位置参数或某个子参数时,应以一个逗号指明所在位置。当缺省最后一个位置参数时,逗号可以省略。
//EXP  JOB  (2000, ,9),CLASS=A
//SYSTEM  JOB  ,SYSTEM,CLASS=S,MSGLEVEL=(0,0)
4. 当没有任何位置参数时,则不必书写任何内容表示。
//EXP  JOB  CLASS=A
5.关键字参数之间没有相对位置的规定,可以按任何次序排列。
//EXP  JOB  2000,CLASS=A,MSGLEVEL=1
也可写作:
//EXP  JOB  2000, MSGLEVEL=1,CLASS=A
6.允许含有特殊字符的参数或子参数,且其中的特殊字符并非起某种特定的语法功能(见表3.2.1)时,必须用撇号“’”替代括号将这些参数和子参数括起来,例:ACCT=’123+456’。而在这些参数与子参数中要用到撇号时,则需两个连续的撇号表示,例:O’NEIL需写作’O’’NEIL’。有些语句中的某些参数或子参数含有一些特定的特殊字符时,将不需要用撇号括起来,详细的情况清参考表3.2.2。在表3.2.1中我们可以知道,在JCL中用 “&”来表识符号参数的开始。当参数中含有“&”且不用来表示符号参数时,则需使用连续的两个“&”来表示“&”。例:
//S1  EXEC  PGM=IEFBR14,ACCT=’&&ABC’
//DD1 DD    DSN=&&TEST,UNIT=SYSDA,SPACE=(TRK,(1,1))
MVS系统中,系统将视连续的两个“&”为一个字符。所以建议用户将含有“&”的参数用撇号括起来以避免出错。
语句、参数或子参数        无需用撇号括起的特殊字符        例子
JOB语句中记账信息参数(accounting information)        连字符“-”        //JOBA  JOB  D58-D04
JOB 语句中程序员名参数(programmer’s-name)        连字符“-” 及 “.”(当“.”出现在字符前、字符间时无需撇号,但当其出现在字符串最后时则需用撇号)        //JOBB  JOB  ,S-M-T//JOBC  JOB  ,.ABC//JOBD  JOB  ,P.D.S//JOBE  JOB  ,’A.B.C.’
EXEC ACCT        连字符“-” 或 “+0”         //S1 EXEC … ACCT=D-L//S2 EXEC … ACCT=D+0
DD VOLUME=SER        连字符“-”        VOLUME=SER=PUB-RD
DD UNIT device-type        连字符“-”        UNIT=3330-1
DD DSNAME        连字符“-”        DSNAME=A-B-C
        分隔数据集名的“.”        DSNAME=A.B.C
        起语法功能的“&&”(见表3.2.1)        DSNAME=&&TEMPDSDSNAME=&&PAYOUT
        “()”,其作用为表示(括起):1.        PDS及PDSE的成员名2.        索引顺序数据集(indexed sequential data set)的域名(area name)3.        PDS及PDSE的生成数据集(generation data set)的代号(generation number)4.        生成数据集的代号        DSNAME=PDS1(MEMA)DSNAME=ISDS(PRIME)DSNAME=GDS(+1)
        标识生成数据集代号的加号“+”及减号“-”        DSNAME=GDS(-2)

表  3.2.2
7.JCL的位置参数与关键字参数最多只能由两级子参数。也就是说用于括起子参数列表的括号最多只能有两层。

四、JCL语句的位置
在下面各界中我们将详细讨论各语句的书写方法,为了便于编写JCL,下面按照JCL语句的放置顺序来说明它们的位置:
1.        JOB 语句。
2.        JOBLIB语句。
3.        JOBCAT及SYSCHK语句。
4.        任何流内过程。
5.        第一个EXEC语句
6.        任何的STEPCAT、STEPLIB,或一般的属于这一步的DD语句。
7.        任何更多的EXEC语句及与他们相关联的DD语句。
8.        任何空语句。
四、        JCL语法实例
作业语句      //EXPJOB  JOB  ,’USERNAME’,MSGLEVEL=(1,1),      EXAMPLE
作业语句续行  //  MSGCLASS=Q,CLASS=A
              //**********************
注释语句      //*  IT IS A EXAMPLE  *
              //**********************
执行语句      //STEP1  EXEC  PGM=IEFBR14
DD语句      //DD1  DD    DSN=MJSN.TEAM01.ONE,DISP=(,CATLG),
DD语句续行  //  SPACE=(TRK,(5,2)), UNIT=SYSDA         
    DD语句      // DD1  DD    DSN=MJSN.TEAM01.TWO,DISP=(,KEEP),
    DD语句续行  //  SPACE=(TRK,(1,1)), UNIT=SYSDA
值得注意的是:在本例中,采取了两种注释说明的方式,一种为作业语句中的“EXAMLE”,这是在说明区中说明的方式;另一种则是注释语句的方式。注释语句以第1~3
列的“//*”开始,可以将它放在JOB语句后的任何JCL语句的前面或后面来说明JCL。

3.2.3        JOB语句
JOB语句标志一个作业的开始、分配作业名并设置相关的位置参数及关键字参数,每个作业的第一个语句必须是JOB语句。
JOB语句的格式如下:
//作业名 JOB  位置参数[,关键字参数][,关键字参数]。。。[注释说明]

一、        作业名
作业名是用户给作业指定的名字。为使操作系统识别作业,必须选择确定的作业名字,由于系统不能同时运行具有相同名字得到作业,因此只能给作业一个唯一确定的名字。一般来说,建议用户采用“用户标识USERID+数字或字符”的作业名,例如用户标识为JACK,则作业名可用JACKA。

二、位置参数
    作业语句中的位置参数有两个:
1.        记账信息(accounting information):
记账信息位于操作符“JOB”后,它用于提供用户使用系统的合法性、及时、纸张的收费管理等。其格式为:
([account-number][,accounting-information]…)
account-number:用户账号;
accounting-information:附加的记账信息,如房间号、部门名等等。
记账信息参数及其子参数最多不可超过143个字符(包括分隔子参数的逗号,但不包括括起子参数列表的括号)。例:
//EXAMPLE1  JOB  (D548-8686,’12/8/98’,PGMBIN)
//EXAMPLE2  JOB  D548-8686

2.        程序员名(programmer’s name)
程序员名用于标识作业的所有者(owner)信息,包括特殊字符在内,其长度不得超过20个字符。例:
//EXAMPLE1  JOB  2000,J.A.C.K
//EXAMPLE2  JOB  2001,JACK
//EXAMPLE3  JOB  2003,’O’’SUN’

下面是几个位置参数不同的书写格式的例子:
带有全部位置参数的作业语句:
//JOBA  JOB  (20008,60),A.B.C,CLASS=S,…
缺省记账信息的作业语句:
//JOBB  JOB  ,USER-NAME,CLASS=A,…  
不带位置参数的作业语句:
//JOBC  JOB  CLASS=Q,…

二、        关键字参数
JOB语句中的关键字参数有如下几个:
1.        ADDRSPC
指明作业所需之存贮类型,它有两个子参数:VIRT及REAL。VIRT表示作业请求虚拟页式存贮,而REAL表示作业请求实存空间。缺省值为VIRT。其格式为:
ADDRSPC={VIRT}
           {REAL}
例:
//PEH  JOB  ,BAKER,ADDRSPC=VIRT
//DEB  JOB  ,ERIC,ADDRSPC=REAL,REGION=100K
2.        BYTES
指明打印作业的系统输出数据集的最大千字节数,同时该参数还指出当超过所给出的最大字节数时,系统对作业的处理方式。这些方式包括:取消作业(转储(dump)或不转储)或继续作业并向操作员发出超过最大字节数的警告信息。其格式为:
BYTE={nnnnn}
      {([nnnnnn][,CANCEL])}
      {([nnnnnn][,DUMP])}
      {([nnnnnn][,WARNING])}

nnnnnn:指明打印输出的最大千字节数,例:nnnnnn取值500,则表示500,000字节。nnnnnn取值范围为:0 ~ 999999。
CANCEL:当作业输出字节数超过nnnnnn时,系统将不转储而直接取消该作业。
DUMP:当作业输出字节数超过nnnnnn时,系统在取消该作业前将发出转储请求。
WARNING:当作业输出字节数超过nnnnnn时,作业继续执行,系统将按照安装时规定的时间间隔不断向操作员发送警告信息。
当BYTE参数或其子参数省略不写时,系统将采用安装时定义的默认值。
例:
//JOB1  JOB  (123456),’R F B’,BYTES=(5000,CANCEL)
// JOB1  JOB  (123456),’R F B’,BYTES=40
除了BYTES参数外,JOB语句中还有另三个参数可以限制作业输出的最大值,其格式及子参数的意义也与BYTES类似,它们是:CARDS、LINES及 PAGES。上述三个参数与BYTES不同之处在于子参数nnnnnn的单位不同,分别是:卡数、行数及页数,读者可以类推使用。
3.        CLASS
CLASS 参数规定了作业的类别,JCL中可选用的作业类别有36个,用字母A~Z及数字0~9表示。相同类别的作业处于同一输入队列等待执行(如图3.2.1),并具有相同的处理属性。作业类别的属性定义在JES中。当CLASS参数缺省时,JES将会根据安装时的缺省值赋予该作业一个缺省的CLASS值。
格式:CLASS=jobclass
         
   
   
   //J1  JOB  … ,CLASS=A, …


    //J2  JOB  … ,CLASS=T
                                 

图 3.2.1
4.MSGCLASS
用于为作业日志(job log)设置输出类别。作业日志是为程序员提供的与作业相关信息的记录。当该参数省略时,系统将会采用默认值。
格式:
MSGCLASS=class

class:定义作业日志的类别。与输入队列相似,class是一个A~Z的字母或一个0~9的数字。
例:
//EXMP1  JOB  ,GEORGE,MSGCLASS=F
5.MSGLEVEL
用于控制JCL作业输出清单的内容,用户可以要求系统打印出如下内容:
JCL语句;
输入流中的所有控制语句,即:所有的JCL语句及JES2或JES3语句;
任何作业步调用的流内过程和编目过程语句;
作业控制语句的信息;
JES及操作员对作业的处理信息:设备和卷的分配、作业步及作业的执行和终止、数据集的处理等。
格式:
MSGLEVEL=([statements][,messages])
   
    statements:指明在JCL作业输出清单中应打印出的作业控制语句的类型,取值范围为:0 ~ 2。
取值0:仅打印出作业的JOB语句;
取值1:打印出作业中包括过程语句在内的所有JCL语句;
取值2:输入流中的所有控制语句。
messages:指明在JCL作业输出清单中应打印出信息的类型,取值范围为:0 ~ 1。
取值0:只有在作业异常终止时,打印出有关JCL、JES、操作员及SMS的处理信息;
取值1:无论作业是否异常终止,都打印出有关JCL、JES、操作员及SMS的处理信息。
例:
//EXMP3  JOB  ,MSGLEVEL=(2,1)
//EXMP4  JOB  ,MENTLE,MSGLEVEL=0
//EXMP5  JOB  ,MIKE,MSGLEVEL=(,0)
6.NOTIFY
用于请求系统在后台作业处理完毕时给指定用户发送信息。如果作业完成时,该用户未在系统登录,则系统所发送的信息将会保留到此用户下次登录。
格式:
NOTIFY={userid}

userid:必须以字母或通配符开头的1~7个字母、数字或通配符组成,其值必须是一个存在的TSO用户标识。
例:
//SIGN  JOB  ,TLOMP,NOTIFY=TSOUSER   
7.PRTY
用于为相应的输入队列中的作业分配优先级。系统根据作业优先级的高低来选择来选择作业执行,对于同一级的作业的选择将采取“先进先出”的原则。
格式:
PRTY=priority

    priority:用数字量来表示优先级,数字越大表示优先级越高。根据作业进入子系统的类型,其取值范围是JES2:0~15;JES3:0~14。
例:
//JOBA  JOB  1,’JIM WEBSTER’,PRTY=12
    8.REGION
用于指定作业所需的实存或虚存空间的大小,系统将在该作业中的每一作业步使用该值。所需空间大小必须包含以下内容:
运行所有程序所需的空间
在运行期间,程序中宏指令GETMAIN所需的所有附加空间
任务初始化和终止时需要的自由空间
如果JOB语句中的REGION参数省略不写的话,系统将采用每条EXEC语句中所定义的REGION参数,当EXEC语句中的REGION参数省略不写时,系统将采用安装缺省值。
格式:
REGION={valueK}
        ={valueM}   

valueK:以千字节(Kb)为单位指出所需空间大小,value可取1~7 位的十进制数,其取值范围为1~2096128。系统以每4k为一存储单位分配空间,所以value值应取4的倍数,如REGION=68K。当 value值不是4的倍数时,系统会将其增至一最为接近的4的倍数的值。
valueM:以兆字节(Mb)为单位指出所需空间大小,value可取1~4 位的十进制数,其取值范围为1~2047
注:REGION值必须是有效的存储空间,如果取值为0或任何大于系统极限的值时都有可能会引起存储问题。当系统未定义极限值时,value值不能超过16384K或16M。
例:
//ACCT1  JOB  A23,SMITH,REGION=100K,ADDRSPC=REAL
//ACCT2  JOB  175,FRED,REGION=250K
9.TIME
用于指定作业占用处理器的最长时间并可通过一些信息得知该作业占用处理器的时间。当作业占用处理器时间超过指定值时,系统将终止该作业。通常情况下,此参数不用设置。当作业所需处理器时间长于系统缺省值时,或出于某种测试目的才设置此参数。
格式:
TIME={([minutes][,seconds])}
     ={1440               }
     ={NOLIMIT          }
     ={MAXIMUM        }

minutes:指定作业可占用处理器最长时间的分钟数,取值范围为0~357912(248.55天)。不可以将TIME参数写作TIME=0,这样将导致不可预知的后果。
Seconds:作为minutes的补充,定义指定作业可占用处理其最长时间的秒钟数,取值范围为0~59。
NOLIMIT:表明作业的运行无时间限制,等同于TIME=1440。
1440:表明表明作业的运行无时间限制,即24小时。
MAXIMUM:表示作业的运行时间为357912分钟。
当JOB语句中的TIME参数没有指明时,每作业步的运行时间限制由以下值决定:
在EXEC语句中TIME参数的值。
当EXE语句中没有设置TIME参数时,采用默认的时间限制值(也就是JES默认作业步时间限制值)。
例1:
//STD1  JOB  ACCT271,TIME=(12,10)
例2:
//STD2  JOB  ,GOR,TIME=(,30)
例3:
//FIRST  JOB  ,SMITH,TIME=2
//STEP1  EXEC  PGM=READER,TIME=1
           
           
           
//STEP2 EXEC  PGM=WRITER,TIME=1
           
在上例中,JOB语句中规定了2分钟的作业运行时间限制,每个作业步允许1分钟,如果任何一个作业步的执行时间超过1分钟,作业将会异常终止。
例4:
//SECOND  JOB  ,JONES,TIME=3
//STEP1  EXEC  PGM=ADDER,TIME=2
            
            
            
//STEP2  EXEC  PGM=PRINT,TIME=2
            
上例中,JOB语句中规定了3分钟的作业运行时间限制,每个作业步允许2分钟,如果任何一个作业步的执行时间超过2分钟,作业将会异常终止。但两个作业步的总共运行时间不得超过作业运行时间限制??3分钟,也即:如果作业步1的运行时间为1.56分钟,则作业步2的运行时间不得超过1.44分,否则作业也会异常终止。
    10.TYPRUN
用于请求特殊的作业处理。TYPRUN可以告知系统如下要求:
在JES2中,将输入作业流直接拷贝到系统输出数据集并对其进行输出处理。
在JES2或JES3中,挂起一个作业,直至某特定事件发生。当该特定事件发生时,操作员根据用户的要求释放该作业,并允许系统选择该作业执行。使用JES2中的/*MASSAGE语句或JES3中的//*OPERATOR语句通知操作员释放该作业。
在JES2或JES3中,对作业的JCL进行语法检查。
  值得注意的是:不能对已经开始的任务(task)设置该参数,否则该作业将会出错。
  格式:
  TYPRUN={COPY     }
           {HOLD     }
         {JCLHOLD }
         {SCAN     }
子参数说明:
COPY(仅支持JES2): 请求JES2将输入作业流直接拷贝到系统输出数据集并对其进行输出处理。系统并不执行该作业。系统输出数据集的类别与该作业JOB语句中MSGCLASS参数定义的信息类别(massage class)相同 。
HOLD:请求系统在执行作业之前将其挂起,等待某特定事件发生后,请求操作员将其释放。如果在作业的输入过程中出现错误,JES将不会挂起该作业。
JCLHOLD(仅支持JES2):请求JES2在JCL执行前将其挂起,直到操作员将其释放。
SCAN:请求系统只对作业的JCL进行语法检查,不执行也不为其分配设备。
例:
//UPDTAE  JOB  ,HUBBARD
//STEP1    EXEC  PGM=LIBUTIL
            
            
            
//LIST     JOB  ,HUBBARD,TYPRUN=HOLD
//STEPA   EXEC  PGM=LIBLIST
            
            
            
上例中,作业UPDATE与LIST在同一个作业流中被提交执行。作业UPDATE的功能是在库中增加一个成员再删除一个成员;作业LIST则列出该库的成员目录。显然,LIST应在UPDATE之后在执行。作业LIST的JOB语句中设置的TYPRUN=HOLD使得保证了这一执行顺序。
如果输入流中或操作员已执行了MONITOR JOBNAMES的命令,当UPDATE执行完后,系统会通知控制台操作员。操作员释放作业后,系统可以选择该作业执行。
    11.其他参数
在JCL的JOB语句中的关键字参数还有:
COND、GROUP、PASSWORD、PERFORM、RD、RESTART、SECLABEL、USER,由于本书篇幅有限,在这里就不再一一介绍了,详细的使用方法读者可以参考《MVS JCL Reference》一书。

3.2.4        EXEC语句
EXEC语句标明作业或过程中的每一作业步的开始,并告知系统如何执行该作业步。包括所有在EXEC语句中调用的过程中的所有作业步在内,一个作业最多可以有255个作业步。
EXEC语句格式如下:
//[作业步名]  EXEC  位置参数[,关键字参数]…[符号参数=值]… [注释]

一、作业步名
作业步名是可以省略不写的,如需标明作业名时,该作业名必须在该作业内以及该作业调用的所有过程中是唯一的,它由1~8个字母或通配符开头的字符数字构成。

二、位置参数
EXEC语句中的位置参数有两个:PGM和PROC。每条EXEC语句必须有且仅有一个位置参数或过程名。
1.        PGM
PGM 参数用于指明所要执行的程序名。该程序必须是一个分区数据集(PDS)的成员或用作系统库(system library)、私有库(private library)及临时库(temporary library)的扩充分区数据集(PDSE)的成员。程序名的调用方法分为直接调用和间接调用。
格式:
PGM={program-name}
     {*.stepname.ddname}
    {*.stepname.procstepname.ddname}
program-name:program-name(程序名)指明要执行程序的成员名或别名。程序名由由1~8个字母或通配符开头的字符数字构成。
*.stepname.ddname:表示要执行的程序名由本作业步前名为“stepname”的作业步内名为“ddname”的DD语句的DSN参数决定。
*.stepname.procstepname.ddname:表示要执行的程序名由本作业步前名为“stepname”的作业步里所调用过程内名为“procstepname”的过程步中相应名为“ddname”DD语句的DSN参数决定。
在上述三种程序调用方法中,第一种为直接调用,而后两种为间接调用。间接调用采用向后参考的方法,这里的“后”指在本作业步读入之前,已先读入系统的本作业其它JCL语句。当需调用的程序在系统库(如SYS1.LINKLIB)或私有库(由作业中的JOBLIB DD语句或本作业步中的STEPLIB DD定义)中时使用第一种调用方法;而当需调用的程序在本作业步前的某一作业步创建的临时库中时采用后两种调用方法。
例:
//JOBC   JOB  ,JOHN,MSGCLASS=H
//STEP2  EXEC  PGM=UPDT
//DDA   DD  DSNAME=SYS1.LINKLIB(P40),DISP=OLD
//STEP3  EXEC  PGM=*.STEP2.DDA
在上例中,名为STEP3的EXEC语句采用程序间接调用方式,所调用的程序名由作业步STEP2中的名为DDA的DD语句决定,在该DD语句中定义了系统库SYS1.LINKLIB,程序P40是该库的一个成员。“P40”即STEP3中要调用执行的程序名。关于DD语句的详细情况我们将在3.2.5中讨论。
2.        PROC
指明作业步所要运行的过程名。
格式:
{PROC=procedure-name}
{procedure-name      }
procedure-name:需要调用的过程名,过程名由1~8个字母或通配符开头的字符数字构成。所调用的过程名可以是:
编目过程的成员名或别名。
由PROC语句定义的流内过程的过程名,该流内过程必须在本作业内且本作业步前定义。
在设定该参数时,可直接写出过程名。
例:
//SP  EXEC  PROC=PAYWRKS
//BK  EXEC  OPERATE

三、        关键字参数
EXEC 语句的关键字参数是可选的,这些参数制作用于本作业步。当EXEC语句的位置参数指定程序名时,关键字参数的写法同JOB语句;当EXEC语句的位置参数指定编目或流内过程时,EXEC语句的关键字参数将覆盖所调用过程中各EXEC语句的关键字参数。因此如果想仅覆盖过程中的某个EXEC语句的关键字参数,则应在设置关键字参数时,同时指出所调用过程的相关过程步的名字。书写形式如下:
关键字参数.过程步名=值
下面将分别介绍EXEC语句中常用的关键字参数:

1.        ACCT
指明作业步所需的一个或多个记账信息子参数。记账信息参子参数最多不可超过142个字符(包括分隔子参数的逗号,但不包括括起子参数列表的括号)。
格式:
ACCT[.过程步名]=(记账信息)
例:
    //STP3  EXEC  PROC=LOOKUP,ACCT=(‘/83468’)
2.ADDRSPC
指明作业步所需之存贮类型,它有两个子参数:VIRT及REAL。VIRT表示作业步请求虚拟页式存贮,而REAL表示作业步请求实存空间,不能进行页式处理。缺省值为VIRT。EXEC语句中的ADDRSPC参数仅在本作业步中起作用,JOB语句中的ADDRSPC参数会覆盖该作业中的所有EXEC语句中的ADDRSPC参数。   
格式:
ADDRSPC[.过程步名]={VIRT}
                     {REAL}
例:
//CAC1  EXEC  PGM=A,ADDRSPC=VIRT
//CAC2  EXEC  PROC=B,ADDRSPC=REAL,REGION=100K
3.REGION
用于指定作业步所需的实存或虚存空间的大小,系统仅在本作业步中使用该值。
格式:
REGION[.过程步名]={valueK}
                  ={valueM}   
    EXEC语句中REGION的子参数定义与JOB语句中相同。
例:
//MKBOYLE  EXEC  PROC=A,REGION=100K,ADDRSPC=REAL
//STEP6   EXEC  PGM=CONT,REGION=250K
4.        TIME
用于指定作业步占用处理器的最长时间,并可通过作业输出清单得知该作业步占用处理器的时间。当作业步占用处理器时间超过指定值时,系统将终止该作业。
格式:
TIME[.过程步名]={([minutes][,seconds])}
               ={1440               }
               ={NOLIMIT          }
               ={MAXIMUM        }
EXEC语句与JOB语句中的TIME参数的子参数的设置方法基本相同。值得注意的是:在JOB语句中不可设置TIME=0,而在EXEC语句中则可以设置TIME=0,当TIME=0时表示本作业步的执行时间由前面作业步的剩余执行时间决定。
例1:
//STP1  EXEC  PGM=ACCT,TIME=(12,10)
例2:
//STP2  EXEC  PGM=PAY,TIME=(,30)
例3:
//FIRST  JOB  ,SMITH  MSGLEVEL=(1,1)
//STEP1  EXEC  PGM=READER,TIME=1
           
           
           
//STEP2 EXEC  PGM=WRITER
           
在上例中,STEP1规定了1分钟的执行时间,STEP2的运行时间将由STEP1决定,也即STEP2的执行时间为:(1分钟 ? STEP2实际运行时间)。
5.        COND
用于对先前作业步执行的返回码(return code)进行测试,以决定是否执行本作业步。用户可以对特定作业步的返回码进行测试也可以对每一执行完毕的的返回码都进行测试。如果测试条件不满足,系统执行本作业步;如果测试条件满足系统则不执行该作业步。作业中的第一个EXEC语句中的COND参数将被系统忽略。注意,当测试条件满足时,系统并非不正常终止该作业步,而只是跳过该作业步,该作业仍将正常执行。
格式:
(1)COND[.过程步名]=(code,operator)
(2)COND[.过程步名]=((code,operator[,作业步名][,过程步名])
                   [,(code,operator[,作业步名][,过程步名])]…[,EVEN])
                                                        [,ONLY]
(3)COND=EVEN
     COND=ONLY
利用COND参数最多可以有8个返回码测试,如果有EVEN或ONLY时,最多有7个测试。格式(1)只有在先前作业步没有非正常终止时,才能进行该测试。格式(2)、(3)测试决定于EVEN和ONLY的设置。
code:系统使用code(测试码)与先前作业步或某特定作业步的返回码进行比较。Code的取值范围为:0~4095。
operater:表示code与返回码的比较类型,这些比较的操作符是:GT(大于)、GE(大于等于)、EQ(等于)、NE(不等于)、LT(小于)、LE(小于等于)。
作业步名:指定先前某一作业步,并用该作业步的返回码与本作业步的测试码进行比较。当省略作业步名时,表示本作业步的测试码将与先前所有作业定额的返回码进行比较测试。
作业步名.过程步名:指定先前某一作业步调用过程的过程步。系统将用该过程步的返回码与给定的测试码进行比较。其中该作业步由“作业步名”指定,而过程步由“过程步名”指定。
EVEN:表示无论即使先前作业步异常终止,本作业步都要执行。当EVEN子参数设定时:
不测试先前任何的异常终止作业步的返回码。
测试那些正常完成的作业步的返回码,如果测试条件全部不满足的话,本作业步将执行。
    ONLY:表示只有先前作业步异常终止,本作业步才执行。当ONLY子参数设定时:
不测试先前任何的异常终止作业步的返回码。
测试那些正常完成的作业步的返回码,如果测试条件全部不满足的话,本作业步将执行。
EVEN与ONLY的具体情况见下表:
EVEN/ ONLY        先前作业步是否异常终止?        测试条件是否满足?        本作业步是否执行?
EVEN        否        否        是
EVEN        否        是        否
EVEN        是        否        是
EVEN        是        是        否
ONLY        否        否        否
ONLY        否        是        否
ONLY        是        否        是
ONLY        是        是        否

例1.
//STEP6  EXEC  PGM=DISKUTIL,COND=(4,GT,STEP3)
在本例中如果STEP3的返回码小于4,系统将不执行STEP6。由于没有设置EVEN或ONLY,如果先前的作业步异常终止,系统将不会执行本作业步。
例2.
//TEST2  EXEC  PGM=DUMPINT,COND=(16,GE),(90,LE,STEP1),ONLY)
由于设置了ONLY子参数,系统只在以下两种情况满足时执行本作业步:
(1)        先前作业步异常终止;
(2)        返回值的测试条件都不满足。
那么对于本例来说,系统将会在以下三种情况都满足的情况下执行本作业步:
一个先前作业步异常终止。
所有先前作业步的返回码大于等于17。
STEP1的返回码小于等于89。
例3.
//STEP1  EXEC  PGM=CINDY
         
         
         
//STEP2  EXEC  PGM=NEXT,COND=(4,EQ,STEP1)
         
         
         
//STEP3  EXEC  PGM=LAST ,COND=((8,LT,STEP1),(8,GT,STEP2))
         
在本例中,如果STEP1的返回码为4,STEP2 将不被执行。在STEP3执行前,系统将执行第一个返回码测试。而由于STEP2并未被执行,所以将不会进行第二个返回码的测试。由于8大于4所以STEP3被执行。
例4.
//STP4  EXEC  PROC=BILLING,COND.PAID=((20,LT),EVEN),
//     COND.LATE=(60,GT,FIND),
//     COND.BILL=((20,GE),(30,LT,CHGE))
在本例中的EXEC语句调用了一个名叫BILLING的过程。这条语句中定义了几个不同的分别对过程步PAID、LATE、BILL的返回码的测试。由于设置了EVEN子参数,除非相应的返回值测试满足条件,那么即使先前作业步异常终止,过程步PAID都将被执行。
6.        PARM
用于向本作业步执行的程序传递变量信息。该程序必须有相应的指令接收这些信息,并使用它们。
格式:
PARM[.过程步名]= 子参数
PARM[.过程步名]=( 子参数, 子参数)
PARM[.过程步名]=(‘子参数’, 子参数)     
PARM[.过程步名]=’子参数, 子参数’
括所有的逗号、撇号以及括号在内,所有子参数的总长度不得超过100个字符。当某子参数中含有特殊字符或空格时,可以将该子参数用撇号括起来,在其它子参数一起用括号括起来,或将所有在参数用撇号括起来。
子参数:包含传递给程序的变量信息。
    例1.
//RUN3  EXEC  PGM=APG22,PARM=’P1,123,P2=5’
在本例中,系统将参数P1、123及P2=5传递给程序APG22。
例2.
// STP6  EXEC  PROC=ASFCLG,PARM.LKED=(MAP,LET)
在本例中系统将MAP、LET传递到过程ASFCLG中名为LKED的过程步。

3.2.5        DD语句
数据定义语句(DD语句)用于定义一个数据集以及该数据集所需的输入输出资源。DD语句相对与前面介绍过的JOB语句和EXEC语句来说,其参数的定义、子参数的设置要复杂一些,在本小节内我们将仅讨论DD语句的一般规则以及部分位置参数,关于DD语句的一些常用参数以及特殊用法我们将用单独的一节讨论。
一、        格式:
//[dd名        ]   DD  [位置参数][,关键字参数]… [注释]
     [过程步名.dd名]
//[dd名        ]   DD  
[过程步名.dd名]
   
二、dd名
“dd 名”是为DD语句定义的名字,它由1~8个字母或通配符开头的字符数字构成。在一个作业步内可以有多个DD语句,但每个DD语句的dd名在本作业步中应该是唯一确定的。“dd名”可以由系统定义也可以由用户自己定义,当用户需要调用公用程序时,需根据公用程序的具体要求选用系统定义的“dd名”。用户自定义的“dd名”不可与系统定义“dd名”相重复。系统定义“dd”名有如下几个:
JOBCAT     SYSCHK  
JOBLIB      SYSCKEOV
STEPCAT    SYSIN
STEPLIB    SYSMDUMP
SYSBEND   SYSDUMP
JES2子系统中:
JESJCLIN   JESMSGLG
JESJCL     JESYSMSG
JES3子系统中:
JCBIN      JESJCL      JS3CATLG
JCBLOCK   JESMSGLG  J3JBINFO
JCBTAB     JOURNAL   J3SCINFO
JESJCLIN   JOURNAL   J3STINFO
JESInnnn    JESYSMSG  STCINRDR
                       TSOINRDR

用户子定义“dd名”可以根据数据的用途,遵循“dd名”的规则来命名,当为应用程序输入输出结果定义数据集时,“dd名”的命名规则取决于程序所用语言的类型。汇编语言由DCB宏指令指定;COBOL预言有ASSIGN子名指定;PL/1语言由DECLARE语句指定;FORTRAN语言由READ或 WRITE语句中的通道号构成。

三、参数
DD语句的参数也分为位置参数及关键字参数,这些参数都是可选的。每个DD语句只能有一个位置参数,但根据需要可以有个关键字参数。位置参数有“*”、“DATA”和“DUMMY”。在本小节中将只介绍位置参数的使用,关键字参数将在下一节中介绍。
1.参数“*”
参数“*”用于开始一个流内数据集。数据记录跟在“DD ”语句之后,其第一、二列不能是“//”或“/*”;该记录可以是任何编码,如EDCBIC。下列符号表明流内数据记录的结束:
输入流中的“/*”。
表示另一个JCL语句开始的“//”。
当数据记录中需以“//”开始时,就必须使用DATA参数来代替“*”参数。
格式:
//dd名  DD  *[,参数]… [注释]
例1.
//INPUT1  DD  *
         
         
          data
         
//INPUT2  DD  *
         
         
          data
         
/*
例2.
//INPUT3  DD  *,DSNAME=&&INP3
         
          data
         
/*
例3.
//STEP2          EXEC  PROC=FRESH
//SETUP.WORK   DD   UNIT=3400-6,LABEL=(,NSL)
//SETUP.INPUT1  DD   *
                 
                 
                 data
                 
/*   
//PRINT.FRM     DD   UNIT=180
//PRINT.INP      DD   *
               
               
                data
               
/*
例3在输入流中定义了两组数据。DD语句“SETUP.INPUT1”定义的输入数据将被编目过程中名为“SETUP”的过程步使用。而DD语句“PRINT.INP”定义的输入数据将被编目过程中名为“PRINT”的过程步使用。
2.        DATA
用作一个流内数据集的开始,该流内数据集里含有以“//”开头的语句。数据记录紧跟在“DD DATA”语句之后;该数据记录可以是BCD或EDCBIC编码。数据记录将以“/*”作为结束。
格式:
//dd名  DD  DATA[,参数]… [注释]
例1.
//GROUP1  DD  DATA
           
           
           data
           
//GROUP2  DD  DATA
           
           
           data
           
/*
例2.
//GROUP3  DD  DATA,DSNAME=&&GRP3
           
           data
           
/*
例3.
//STEP2      EXEC  PROC=UPDATE
//PREP.DD4   DD   DSNAME=A.B.C,UNIT=3350,VOLUME=SER=D88230
//            SPACE=(TRK,(10,5)),DISP=(,CATLG,DELETE)
//PREP.IN1   DD   DATA
            
            
             data
            
/*   
//ADD.IN2   DD   *
         
            
            data
            
/*
3.        DUMMY
DUMMY参数用于标明:
(1)        没有设备或外存空间分配给该数据集。
(2)        对该数据集不进行状态处理。
(3)        对BASM或QSAM来说,不对该数据集作输入输出操作。
用户使用DUMMY参数对程序进行测试。当测试完成时,如果用户希望恢复对数据集的输入输出操作时,只需将DD  DUMMY参数替换成完整的数据集定义DD语句。DUMMY的另一个用途是在编目或流内过程中,这将会在本章后续节中讨论。
格式:
//dd名  DD  DUMMY[,参数]…
所有在DUMMY语句中的参数必须在语法上是正确的。系统将对他们进行语法检查。
例1.
//OUTDD1  DD  DUMMY,DSNAME=X.X.Z,UNIT=3380,
//               SPACE=(TRK,(10,2)),DISP=(,CATLG)
本例中DD语句“OUTDD1”定义了一个空数据集。该语句中除DUMMY以外的参数将接受系统语法检查但并不起作用。
 
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
大型机学习之具体技术之-JCL练习(四)-特殊的DD语句 - Alex的学习之路 - CS...
成都面试题:
怎样让sqlserver后台定时执行某个存储过程?
COBOL POINT
ETL学习笔记之四:开源项目 Kettle
oracle job的创建和删除
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服