2.5 向后引用(Backward Reference)
一个典型的JCL作业步可以使用或建立好多个数据集,每个数据集都需要在JCL中编写不同的参数区描述它们。向后引用(Backward Reference)是一种编码技术,使得系统可以复制当前作业流中已经定义过的数据集的属性。换句话说,向后引用是作业控制语言的一种功能,它允许用户复制本作业中前面已出现过的信息或引用本作业前面已出现过的数据定义(DD)语句中的参数。
向后引用技术是效率非常高的JCL编码技术,因为程序员可以避免重复编写已有的参数信息。常用的4种向后引用的参数如下。
● 引用程序(PGM):指向前面定义过的程序名的数据集。
● 引用数据集名字(DSN):指向前面定义过的数据集。
● 引用卷名(VOL):指向前面已用过的卷名。
● 引用数据控制块(DCB):指向前面已定义过的数据集的DCB。
向后引用的通用格式如下。
● 在同一个作业步中引用前面的DD语句:Keyword=*.ddname。
● 引用前面作业步中的DD语句:Keyword=*.stepname.ddname。
● 引用编码过程中的前面作业步的DD语句:Keyword=*.stepname.procstep.ddname。
在上面格式中的关键字(keyword)可以为:PGM、DSN、VOL或DCB。下面的作业流例子演示了上面所有4种向后引用的情况,该作业流是你调试程序的好帮手,因为它可以一口气完成你的程序的编译、链接和运行。
000001 //IBMUSERC JOB 168,NEWMAN,CLASS=A,MSGCLASS=H, 000002 // NOTIFY=&SYSUID,MSGLEVEL=(1,1) 000003 // SET SRC=BKUPD1 000004 //* --- COMPLIE PROGRAM BKUPD1----------------------------------- * 000005 //COBOL EXEC PGM=IGYCRCTL,REGION=2048K, 000006 // PARM='NODYNAM,LIB,OBJECT,RENT,RES,APOST,MAP,XREF,OFFSET' 000007 //STEPLIB DD DSNAME=COBOL.V3R1.SIGYCOMP,DISP=SHR 000008 //SYSPRINT DD SYSOUT=* 000009 //SYSIN DD DSN=IBMUSER.TEST.COBOL(&SRC),DISP=SHR 000010 //SYSLIB DD DSN=IBMUSER.TEST.COPY,DISP=SHR 000011 //SYSLIN DD DSNAME=&&LOADSET,UNIT=SYSDA, 000012 // DISP=(MOD,PASS),SPACE=(TRK,(3,3)), 000013 // DCB=*.SYSIN 000014 //SYSUT1 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000015 //SYSUT2 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000016 //SYSUT3 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000017 //SYSUT4 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000018 //SYSUT5 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000019 //SYSUT6 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000020 //SYSUT7 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000021 //* --- LINK EDIT PROGRAM BKUPD1--------------------------------- * 000022 //LKED EXEC PGM=HEWL,COND=(8,LT,COBOL),REGION=1024K, 000023 // PARM='LIST,XREF' 000024 //SYSLIB DD DSNAME=CEE.SCEELKED,DISP=SHR 000025 // DD DSN=IBMUSER.TEST.LOAD,DISP=SHR 000026 //SYSPRINT DD SYSOUT=* 000027 //SYSLIN DD DSNAME=*.COBOL.SYSLIN,DISP=(OLD,DELETE) 000028 //SYSLMOD DD DSNAME=&&LOAD(&SRC),DISP=(NEW,PASS), 000029 // SPACE=(TRK,(3,3,3)), 000030 // VOL=REF=*.COBOL.SYSIN, 000031 // UNIT=SYSDA, 000032 // DCB=(DSORG=PO,RECFM=U,LRECL=0,BLKSIZE=32760) 000033 //SYSUT1 DD UNIT=SYSDA,SPACE=(TRK,(10,10)) 000034 //* --- RUN PROGRAM BKUPD1-------------------------------------- * 000035 //GOBKUPD EXEC PGM=*.LKED.SYSLMOD 000036 //SYSOUT DD SYSOUT=* 000037 //SYSPRINT DD SYSOUT=* 000038 //SORTOUT DD SYSOUT=* 000039 //SYSUDUMP DD SYSOUT=* 000040 //BKTRAN DD DSN=IBMUSER.TEST.BKTRAN.SORT,DISP=SHR 000041 //BKMASTO DD DSN=IBMUSER.TEST.BKMASTO.SORT,DISP=SHR 000042 //BKMASTN DD DSN=IBMUSER.TEST.BKMASTN,DISP=SHR
在上面的例子中,我们首先在第13行向后引用了DCB,即在同一个作业步COBOL中数据集SYSLIN引用数据集SYSIN的DCB。DCB向后引用技术使得你可以将前面已经定义的数据集的DCB数据引用到当前的数据集中。向后引用的DD既可以是同一个作业步的,也可以是之前作业步的,只要该数据集比当前数据集先定义即可。
这种编写方法可以确保当前定义的数据集具有与前面定义的数据集相同的属性,即它们在同一个作业内是一致的。它也能用于覆盖或增加某些子参数到前面定义的DCB参数中。DCB向后引用的一般格式是:
//ddname DD DCB=*.stepname.ddname
在上面的例子中,我们将数据集SYSIN的定义完整地复制到了SYSLIN中,事实上,我们在复制的同时还可以覆盖某些原有的属性。
覆盖之前语句中的属性的一般格式是:
DCB=(*.stepname.ddname,list-of attributes)
比如,如果我们希望数据集SYSLIN的块大小(BLKSIZE)变成3200,而不是数据集SYSIN现在的800,则可以将第13行的DCB=*.SYSIN改成DCB=(*.SYSIN,BLKSIZE=3200)。
第27 行的DD语句用到了数据集名(DSN)的向后引用。这种编码技术使得你在当前作业步中直接访问已经定义在前面作业步中的文件。当你的作业有多个作业步,而它们又要访问相同的文件时,这个技术的优点就体现了出来。在上面的例子中,我们采用这种技术访问了临时文件,这样我们完全不用知道该临时文件的实际名字,就能达到处理的目的了。
数据集名(DSN)向后引用的一般格式是:DSN=*.stepname.ddname。在我们第27行中,使用的是://SYSLIN DD DSNAME=*.COBOL.SYSLIN,其中,COBOL是前一个作业步的名字。
第30行的语句使用了卷名(VOLUME)向后引用技术。该技术使得你可以指向前面定义的数据集所使用的卷名(卷序列号,Volume Serial Number)。当你希望新建立的数据集与原来的数据集存放在同一个卷上而又不知道原来的数据集的卷名时,卷名向后引用技术就非常方便了。卷名向后引用的一般格式是:
//ddname DD …VOL=REF=dsname
在我们的例子中,第30行的语句VOL=REF=*.COBOL.SYSIN将新建立的数据集SYSLMOD与已有的数据集SYSIN存放到同一个卷上了。
最后在第35 行我们看到了程序(PGM)向后引用。程序向后引用技术使你可以直接访问前面编译链接后产生的装载模块(LOAD MODULE)。该装载模块通常存放在程序库的成员中。
程序向后引用技术在程序开发环境下是非常有用的,因为在这种环境中,就像我们上面的例子那样,编译链接后的程序马上就会在下一个作业步运行。这种情况下,与其为正在开发的程序取个名字,还不如直接使用程序的向后引用方法搞定。程序(PGM)向后引用的一般格式是:
//STEP EXEC PGM=*.stepname.ddname
程序向后引用通常跟在链接(linkage edit)作业步的后面。在这种情况下,装载模块即程序是存放在临时数据集中的。在接下来的运行作业步中,使用程序的向后引用就非常方便。这种引用直接将要运行的程序指向前一个作业步输出的程序。
在上面的例子中,作业步LKED(LINKEDIT)要求系统将生成的装载模块存放在临时数据集中,其DD名字为SYSLMOD,而数据集的名字是&&LOAD(&SRC),其中,&SRC是一个JCL符号参数(变量),其值是在第3行的SET语句中赋值的。DISP参数指定为NEW和PASS,表示要传送(PASS)到下一个作业步。接下来,作业步GOBKUPD使用程序向后引用技术执行该程序。