IBM主机技术一本通
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.3 世代数据集GDG

世代数据组是一些有关联的数据集的集合,通常按年月日的顺序建立。使用GDG去控制这类数据集组的建立和保持的时间,可以简化数据集的管理。建立第一代GDG之前,需要两个步骤:第1步,使用AMS定义包含管理数据组规则的世代数据组的基本要素;第2步,创建独立数据集的DCB参数,必须建立一个模板。

世代数据集组GDG(Generation Data Group)是一组编目的数据集,其组内的每一个数据集称为世代数据集或一代数据集,它们具有相同的名字且在时间序列上是相关的。如要求保留一年内的工资发放数据,每月的工资数据集就是一个世代数据集,全年12个月的工资数据集便构成了一个世代数据集组。

世代数据集可以是顺序数据集或分区数据集,它可以写在磁盘或磁带上,但一个GDG的所有数据集应驻留在相同介质上。由于一个GDG中的所有数据集都使用相同的名字,所以要区分各个世代数据集,就要使用世代编号。世代编号可以是相对编号或绝对编号。系统在维护GDG时使用绝对编号,而应用程序员则通常使用相对编号。

● 相对编号

假设有一个三代的GDG,TEST.GDG(其中这3代数据集分别为8、9、10 3个月份的数据,10月份数据为当前代数据集),则当前一代数据集(10月份的数据集)表示为DSN=TEST.GDG(0),上一代数据集(9月份的数据集)表示为DSN=TEST.GDG(-1),更早一代的数据集(8月份的数据集)表示为DSN=TEST. GDG(-2)。

如果在该GDG中要产生新一代数据集(11月份的数据),则可写为DSN=TEST.GDG(+1)。由此可见这些相对编号是相对于当前一代数据集而言的,当前一代数据集用零表示,在当前一代之前存入的世代数据集用负数表示,在其后存入的世代数据集用正数表示。

● 绝对编号

在每一个GDG名后加一个后缀GxxxxVyy,其中xxxx为绝对世代编号,yy是版本号(00~99),如果DSN=TEST.GDG(0),对应的实际名字为TEST.GDG.G0003V00,则DSN=TEST.GDG(-1),则对应的实际名字为TEST.GDG.G0002V00。类似地,DSN=TEST.GDG(-2)的数据集其对应的实际名字为TEST.GDG.G0001V00。

图3.12是GDG的绝对编号和相对编号的编写示意图。

图3.12 GDG的相对编号和绝对编号

3.3.1 GDG的定义及建立

在建立GDG时,首先要为这个世代数据集组指定一个数据调用模式(DSCB模式),如系统中已经有这样的模式,可直接通过DCB参数引用,若没有这样的模式,则需要自己建立这个模式。注意,这个模式必须和所建立的GDG在同一个编目卷上。

在DSCB模式中应包括卷名、卷标、GDG数据集名、空间大小、数据控制块等。当GDG中的各代数据集的数据组织结构、属性不同时,则要定义多个模式为不同的数据集提供不同的DCB信息。DSCB模式的建立方法可以使用DEFINE GENERATIONDATAGROUP命令来定义。其语法格式为:

        DEFINE GENERATIONDATAGROUP
          (NAME(entryname)
          LIMIT(limit)
          [EMPTY  |  NOEMPTY]
          [SCRATCH  |  NOSCRATCH]
          [TO(date)  |  FOR(days)])

          [CATALOG(catname[/password])]

其中的参数有:

● LIMIT指定世代数据集的最大代数的值(从1~255)。

● EMPTY指定当数据集达到规定的最大代数时,GDG中的所有数据集都要从目录中移出(UNCATALOG),然后将新数据集登目(CATALOG)到GDG数据集中。

● NOEMPTY(默认值)指定当数据集到达规定的最大代数时,只有最老的世代数据集会从目录中移除。

● SCRATCH指定当世代数据集从目录中移出时,同时要将世代数据集项目从VTOC中删除,这个世代数据集将不存在。

● NOSCRATCH(默认值)指定当世代数据集从目录中移出时,其在VTOC中登记的项目不用同时从VTOC中移出。

当建立世代数据集时,新数据集的DCB信息必须来自模板数据集,模板数据集不占用任何存储空间,只是像一个VTOC项目一样存在,模板与编目的GDG必须在同一个卷上。因为GDG的基本名已经在目录中,模板(也拥有同样的名字)不能编目。

一种常用的方法是在整个系统内建立一个单独的模板DSCB,用于系统上的所有世代数据集目录。当建立新世代数据集时,通过覆盖模板的DCB参数来建立你需要的数据集。

下面的作业流建立一个模板DSCB文件TEST.GDG.MODEL,并定义一个GDG文件TEST.GDG。

        000001 //IBMUSERA JOB 168,'NEWMAN LV',CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
        000002 // NOTIFY=IBMUSER
        000003 //IDCAMS  EXEC PGM=IDCAMS,REGION=4096K
        000004 //MODEL   DD  DSN=TEST.GDG.MODEL,DISP=(NEW,CATLG),
        000005 //           UNIT=3390,
        000006 //           SPACE=(TRK,0),
        000007 //           DCB=(RECFM=FB,LRECL=80,BLKSIZE=3120)
        000008 //SYSPRINT DD  SYSOUT=A
        000009 //SYSIN   DD  *
        000010   /* DELETE GENERATION DATA GROUP, IF IT EXISTS           */
        000011   DELETE TEST.GDG GENERATIONDATAGROUP
        000012   SET MAXCC=0
        000013
        000014   /* DEFINE GENERATION DATA GROUP                       */
        000015   DEFINE GENERATIONDATAGROUP (                   -
        000016                     NAME(TEST.GDG)              -
        000017                     LIMIT(3)                   -
        000018                     NOEMPTY                    -
        000019                     NOSCRATCH                  -
        000020 /*
        000021 //

第4行到第7行的JCL语句建立一个GDG模板文件,用于给我们后面往数据集中写数据集时用。注意为模板数据集指定的SPACE是(TRK,0),即没有为模板分配任何空间,因为我们只需要它的文件属性方面的信息。

第11行的DELETE语句删除要定义的GDG,以避免重复。第12行的SET语句将MAXCC置为0,这样即使删除不成功也不会出错。

第15行到第19行的DEFINE定义我们的新GDG数据集TEST.GDG,其最大的代数(LIMIT)为3,NOEMPTY参数告诉我们,如果最大代数达到时,只将最老的一代从目录中移除(UNCATALOG),NOSCRATCH则告诉我们,当数据集从目录中移除时,不需要将数据集在VTOC中的项目同时移除,即仍然保留它在VTOC中的项目。这条DEFINE语句的结果就是在系统中建立了一个空GDG文件TEST.GDG,如图3.13所示。

图3.13 空GDG文件TEST.GDG

3.3.2 GDG文件的应用

下面的例子说明将任何数据写到GDG文件中。假定我们的银行交易文件每天有3种类型,它们分别是放款(Loans)交易、存款(Deposit)交易和信用卡(Credit)交易。我们首先使用下面的作业流将放款交易文件存放到GDG中。

        000001 //IBMUSERA JOB 168,'NEWMAN LV',CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1),
        000002 // NOTIFY=IBMUSER
        000003 //CDS1    EXEC PGM=IEBGENER
        000004 //SYSPRINT DD SYSOUT=*
        000005 //MODEL   DD  DSN=TEST.GDG.MODEL,DISP=OLD
        000006 //SYSUT1   DD DSN=IBMUSER.TEST.BKTRAN.LOANS,DISP=SHR
        000007 //SYSUT2   DD DSN=TEST.GDG(+1),DISP=(NEW,CATLG,DELETE),
        000008 //  SPACE=(TRK,(3,3)),DCB=*.MODEL
        000009 //SYSIN   DD DUMMY
        000010 /*
        000011 //

第7行的TEST.GDG(+1)表示在GDG中增加一代新的数据,第8行的向后引用将我们前面建立的模板数据集的DCB数据引用到新加的数据集中。这样,作业执行完后,TEST.GDG数据集中就有了一个新文件或新代数,其结果如图3.14所示。

同样的,我们可以将存款和信用卡部分的交易文件也放到GDG中(具体的JCL与上面的类似,只需要将第6行的SYSUT1的文件名修改一下就可以了,这里就不重复了),这时,GDG中的内容就会分别变为图3.15中左边和右边的样子。

图3.14 加入一个新文件的GDG数据集

图3.15 加入存款和信用卡文件的GDG数据集

这时候,整个系统中的GDG数据集可以用图3.16来表示。从图中我们可以看到,我们的TEST.GDG中已经有了三代数据,分别是信用卡数据(相对代数为0,绝对代数为G0003),它是数据集中的最新代数。它之前的一代数据集存放的是存款数据,它的相对代数为-1,绝对代数为G0002。同样地,最先进入GDG数据集的放款交易的相对代数则为-2,绝对代数为G0001。数据集在系统中的结构可以用下图表示,从中你可以看出绝对代数与相对代数的关系,以及GDS基数据集(BASE)与实际数据集的关系。

图3.16 GDG数据集的完整内容

如果现在又有新的一天的数据到了,也要写到TEST.GDG中,这时我们定义的最大代数(LIMIT)就超过了。由于我们定义GDG时选用的是NOEMPTY选项,该选项告诉系统,GDG中最老的一代数据即原来的放款交易数据就会从GDG目录中移除(UNCATALOG)。这时,TEST.GDG数据集的数据的代数就会如图3.17所示,变成:

最当前数据:相对数据集代数为0,绝对数据集代数为G0004。

上一代数据:相对数据集代数为-1,绝对数据集代数为G0003。

● 再上一代数据:相对数据集代数为-2,绝对数据集代数为G0002。

再老一代数据:即绝对代数为G0001的放款交易数据已经从TEST.GDG中删除了。

图3.17 GDG数据集代数溢出时的处理