Schubie's discussion about dynamic allocation is valuable, but it requires Assembler knowledge to use it. This is why I discussed BPXWDYN, which is readily available to high level or some ways Rexx can be used.
There are a few JCL constructions, such as relative generations, that are best avoided in dynamic allocation (including BPXWDYN), and some tape related combinations that can't be done at all. For example, JCL like this -
//SORTIN DD DISP=SHR,UNIT=(,2),DSN=a-multi-volume-tape-dataset
//SORTOUT DD DISP=(,CATLG),UNIT=AFF=SORTIN,DSN=a-new-sorted-dataset
can not be done in dynamic allocation. The SORTIN DD statement can be done in dynamic allocation, but the UNIT=AFF business in the SORTOUT DD statement to use the same drives as were uses by the SORTIN DD statement cannot be done in dynamic allocation. There are other tape related, though uncommon, things you can do in JCL that can't be done in dynamic allocation, though a clever Assembler programmer can replicate them.
Now I've been doing MVS dynamic allocation for more than 30 years, so it doesn't scare me, but most people (and organizations) are terribly afraid of Assembler, so it can't be used much of the time.