JCL创建数据集是否已存在

时间:2017-11-11 16:54:14

标签: mainframe zos jcl

我想编写一些JCL来创建数据集,其要求是:

  1. 如果数据集不存在,请创建
  2. 和其中之一:

    1. 如果数据集已存在,则覆盖它
      1. 如果数据集已存在,则不执行任何操作
      2. 据我所知,(1)可以用DISP = NEW来完成,(2)可以用DISP = OLD来完成,但是我无法从文档和我的课程材料中找出如何在同时。如果数据集存在,则NEW抛出JCL错误,如果不存在则OLD抛出一个JCL错误。我不知道怎么做(3)。

        我知道有很多方法可以查询JCL中是否存在数据集,但我们尚未涵盖这些数据集,所以我认为没有它可以吗?

4 个答案:

答案 0 :(得分:5)

我认为您正在寻找一代数据组。这不会覆盖现有数据集,但每次执行JCL时都会为您提供一个新数据集。

在前面,您必须使用记录为here的IDCAMS命令创建生成数据组基本条目。这是一次性操作。

//MAKEGDG1 EXEC PGM=IDCAMS
//SYSPRINT DD  SYSOUT=*
//SYSIN    DD  *
 DEFINE GDG (NAME(MY.DSN) LIMIT(255))
//*

要使用它,您可以编写JCL,例如......

//USEGDG1  EXEC PGM=IEFBR14
//DD001    DD  DISP=(NEW,CATLG,DELETE),
//             DSN=MY.DSN(+1),
//             SPACE=(...),
//             and so on

... (+1)表示在组内创建新一代。实际创建的是名为MY.DSN.G####V00的数据集,其中####是系统为您管理的序号,但您始终可以使用MY.DSN(0)获取最新一代。您可以使用MY.DSN(-1)使用前一代到最新一代。

如果您编写MY.DSN代码DELETE而没有在parens中指定世代号,则需要注意一些事项。

如果GDG不是您正在寻找的,您还可以在为新数据集编目的步骤前编写IDCAMS步骤。 IDCAMS步骤的目的是删除数据集。如果数据集不存在,IDCAMS IF MAXCC=12 THEN SET MAXCC=0命令将为您提供错误的返回码(12,如果内存服务),但您可以在这些情况下通过编码DISP=(MOD,CATLG)来修改它。

根据允许的内容进行更新

如果您想要的是创建数据集(如果它尚未存在),并且追加,则可以使用DELETE来完成。我不相信有一种方法可以实现你所说的目标,而无需使用IDCAMS或编写一个基本上与IDCAMS DISP=(NEW,CATLG)相同的clist或Rexx程序。

如果数据集已存在,您可以编码//CKEXIST1 EXEC PGM=IEFBR14 //DD001 DD DISP=OLD,DSN=MY.DSN //* //IF001 IF CKEXIST.RUN=TRUE THEN //* step with DISP=OLD // ELSE //* step with DISP=NEW //IF001E ENDIF 并让作业失败。这是可怕的事情,但我认为它符合您的标准。

我现在无法对此进行测试,但您可能会尝试...

{{1}}

......但即使它有效,我仍然觉得它很难看。这个想法是IEFBR14步骤不会执行,因为数据集分配将失败。 IF001语句正在检查该步骤是否已运行,如果数据集不存在,我将认为将测试为false,如果存在,则为true。不是我推荐用于生产作业流的东西。

答案 1 :(得分:3)

通常,我在创建数据集之前先创建一个步骤以删除数据集。虽然我使用DISP =(MOD,DELETE)。 SPACE =(TRK,0)实际上是一个空值,因为我们将删除DSN或分配没有空间以删除它。这与@bruce_martin的答案之间的区别在于,数据集的创建与实际编写数据集的步骤有关。

这意味着如果文件不存在,则创建该文件,如果存在,则使用该文件,并且DELETE说在步骤终止时将其删除。最终结果是,无论下一步是否存在,都将删除DSN。

这里是一个例子,

//DEL0010  EXEC PGM=IEFBR14
//DSN2DEL  DD   DSN=dataset.to.write.to,DISP=(MOD,DELETE),
//              SPACE=(TRK,0),UNIT=SYSALLDA
//*
//STEP0010 EXEC PGM=MYPROG
//DSN2CR8  DD   DSN=dataset.to.write.to,DISP=(,CATLG,DELETE),
//              SPACE=...,UNIT=...

使用这种方法可确保下一步没有数据集,因此您不必担心有条件的重启。

答案 2 :(得分:2)

@cschneids是一个很好的解决方案;但要做1& 2你可以做到

//CREATE   EXEC PGM=IEFBR14
//DD001    DD  DISP=(MOD,CATLG,DELETE),
//             DSN=MY.DSN,...
//*
//USEGDG1  EXEC PGM=MYPGM,COND=(0,NE)
//DD001    DD  DISP=OLD,
//             DSN=MY.DSN

对于选项3,您可以使用IDCAMS

答案 3 :(得分:1)

创建一个带有额外步骤的jcl(自从我写JCL以来已经21年了,所以我会给你准确的编码)。

// step1 exec pgm=idcams
  rename my.dsn in my.otherdsn
/*
//step2 exec pgm=idcams, cond=(0, eq, step1)  rename successful: rename back
 rename my.otherdsn in mydsn
/*
//step3 exec pgm=IEFBR14, cond=(0, ne, step1) did not exist, create it
//mydsn dd my.dsn,disp(new,catlg), etc
/*
//step4a exec pgm=myprogram, parm='EXISTS", cond=(0, eq, step1)
// ....
//step4b exec pgm=myprogram, parm='NEW", cond=(0, ne, step1)
// ....

使用myprogram的parm来计算你的程序逻辑!

这样的事情对我们来说也能自动恢复文件:第一步重命名一个b。如果失败,则作业已中止,因此step2将恢复数据库。然后包括实际工作jcl。作业的最后一步重命名为。

中的b