JCLを使ってプログラムを動かすとき、DD文で新規にデータセットを作ってそこへアウトプットを出す場合に使うのが「DISP=(NEW,…)」。
テストの時など失敗したら同じJCLでRE-RUNを掛けたりするが、2回目以降はデータセットが出来てしまっているので、先行にDELETEのステップを追加するなど、1回目の実行で出来てしまった中途半端なデータセットを消さなきゃいけないのがちょっと面倒だったりする。
ABENDした場合は、DISPの後処理でDELETEさせることができるが、ノーマルエンドでも結果が × ってことはよくあり、この場合はABENDしてないので出力先データセットはできてしまう。カタログしないデータセットなら、先行にDELETEのステップを常に入れておけばいいのだけどやはり面倒ではある。
このような時、日立のVOS3にはDISPの第1パラメーターに「RNW」って言うのが指定できる。RENEWですね。新規の割り当てをするという意味ではNEWと同じなのだが、同名データセットが存在していれば一旦それをスクラッチしてから新たに作成し直してくれるという機能を持つ。このRNW、使ってみると結構便利。z/OS(MVS)とMSPでは使えないのが残念な、これはいいよなって思う機能です。
1 2 3 4 5 6 7 8 |
//COPYPDS EXEC PGM=JSDPCPY //SYSPRINT DD SYSOUT=* //SYSUT1 DD DISP=SHR,DSN=USR1.JCL //SYSUT2 DD DISP=(RNW,CATLG),DSN=WRK1.TESTDS1, // UNIT=SYSDA,VOL=SER=WORK10,SPACE=(CYL,(10,2,20)) //SYSIN DD * COPY INDD=SYSUT1,OUTDD=SYSUT2 // |
- VOS3システム限定:同名データセットが存在すれば一旦削除して作り直す例
z/OSとMSPには、JCLにDISP=RNW機能がないので、先行に古いデータセットを削除するステップを追加することになりますが、以下にその例を示します。
1 2 3 4 5 6 7 8 9 10 11 |
//SCRATCH EXEC PGM=IEFBR14 //SYSUT2 DD DISP=(OLD,DELETE),DSN=WRK1.TESTDS1, // UNIT=SYSDA,VOL=SER=WORK10 //* //COPYPDS EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=* //SYSUT1 DD DISP=SHR,DSN=USR1.JCL //SYSUT2 DD DISP=(,KEEP),DSN=WRK1.TESTDS1, // UNIT=SYSDA,VOL=SER=WORK10,SPACE=(CYL,(10,2,20)) //SYSIN DD DUMMY // |
- 先行ステップで古いデータセットを削除する例
UNITとVOLを定義したDISP=(OLD,DELETE)は、例え、データセットが存在しなくてもエラーにならないことを利用したものです。
ただし、このサンプルがきれいに動くのは、出力データセットをカタログしない場合に限ります。出力データセットがカタログされている場合は、先行の削除ステップでUNITとVOLパラメーターを指定しなければよいが、2回目以降の実行でないと上手く動かない(初回は出力先データセットが存在しないためカタログ参照でエラーとなりJCLエラーになってしまう)。だからといってUNITとVOLパラメーターを指定すると、2回目以降の実行でデータセットは削除されてもカタログは残ってしまうことになります。そのため、後続ステップでカタログに失敗(NOT CATLG 2)します。同じVOLへの再作成ならまだしも、異なるVOLへの作成だとカタログと矛盾することになり後で面倒なことになってしまいます。
今日のz/OSの運用では、基本的にデータセットはカタログして利用することになっているので、さらにひと工夫必要になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// JOB //* // SET OUTDS=WRK1.TESTDS1 //* //SCRATCH EXEC PGM=IEFBR14 //SYSUT2 DD DISP=(MOD,DELETE),DSN=&OUTDS, // UNIT=SYSDA,SPACE=(TRK,1) //* //COPYPDS EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=* //SYSUT1 DD DISP=SHR,DSN=USR1.JCL //SYSUT2 DD DISP=(,CATLG),DSN=&OUTDS, // UNIT=SYSDA,VOL=SER=WORK10,SPACE=(CYL,(10,2,20)) //SYSIN DD DUMMY // |
- 先行ステップで古いカタログ済みデータセットを削除する例(以前にコメントをくれたNishioiさんのサンプルを流用して修正したもの)
出力先データセットがカタログされるのであれば、この例のように先行の削除ステップでのDISPにはOLDではなくMODを指定し、VOLを指定しないことがポイントです。
データセットが存在していれば削除とアンカタログがなされ、存在していなければ一旦ストレージ・ボリュームに割り振られて削除されます(MODはなければ作り、あれば最終レコードに追加する、という特性を持つ)。出力先データセットがカタログされる場合、このサンプルに習えば、初回の実行(旧データセットが無い状態)でも2回目以降(旧データセットがある状態)の実行でも両方正しく動きます。
なお、同じDSNの重複記述は修正漏れなどを誘発しやすいので、SETステートメントで実際の名前を割り当てるようにしてあります。※SETステートメントは、z/OSでのみ利用可能です(MSPにも同様の機能はあるが、プロシージャー内でしか使えなかったはず…)。