Search code examples
mainframezosjcl

JCL to create dataset whether it already exists or not


I want to write some JCL to create a dataset, with the requirements that :

  1. if the dataset doesn't exist, create it

and either:

  1. if the dataset already exists, overwrite it

or

  1. if the dataset already exists, do nothing

As I understand it, (1) can be accomplished with DISP=NEW, and (2) with DISP=OLD, but I can't figure out from the docs and my course material how to do both at the same time. NEW throws a JCL error if the dataset exists and OLD throws one if it doesn't. I have no idea how to do (3).

I understand there are ways to query if a dataset exists within JCL, but we haven't covered that yet, so I assume it's possible without?


Solution

  • I think you're looking for a generation data group. This wouldn't overwrite the existing dataset, but would give you a new dataset every time your JCL is executed.

    Up front you must create the generation data group base entry with an IDCAMS command documented here. This is a one time operation.

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

    To use this, you write JCL such as...

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

    ...where the (+1) means to create a new generation within the group. What is actually created is a dataset with the name MY.DSN.G####V00, where #### is a sequential number managed for you by the system, but you can always get the most current generation with MY.DSN(0). You can use the previous to the most current generation with MY.DSN(-1).

    Some care is required, if you code MY.DSN without specifying a generation number in parens you will get all extant generations.

    If a GDG is not what you're looking for, you could also code an IDCAMS step in front of your step cataloging your new dataset. The purpose of the IDCAMS step would be to delete the dataset. The IDCAMS DELETE command will give you a bad return code (12, if memory serves) if the dataset doesn't exist, but you can modify that by coding IF MAXCC=12 THEN SET MAXCC=0 under those circumstances.

    Update per additional restrictions on what's allowed

    If what you want is to create the dataset if it doesn't already exist and append to it if it does, that can be accomplished with DISP=(MOD,CATLG). I don't believe there is a way to accomplish your goal as stated without using either IDCAMS or writing a clist or Rexx program that does essentially what the IDCAMS DELETE does.

    You could code DISP=(NEW,CATLG) and let the job fail if the dataset already exists. It's a terrible thing to do, but I think it meets your criteria.

    I'm not in a position to test this right now, but you might try...

    //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
    

    ...but even if it works I still think it's pretty ugly. The idea is the IEFBR14 step won't execute because the dataset allocation will fail. The IF001 statement is checking to see if the step ran, and I think that will test false if the dataset doesn't exist and true if it does. Not something I'd recommend for a production jobstream.