DISP=RNWって便利です(再掲)
今さらですが、追記して再掲載します。
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では使えないのが残念な、これはいいよなって思う機能。
VOS3システム限定:同名データセットが存在すれば一旦削除して作り直す例 //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 //
z/OSとMSPには、JCLにDISP=RNW機能がないので、先行に古いデータセットを削除するステップを追加することになるが、以下にその例を示します。
先行ステップで古いデータセットを削除する例 //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の運用では、基本的にデータセットはカタログして利用することになっているのでひと工夫必要になる。
先行ステップで古いカタログ済みデータセットを削除する例 (以前にコメントをくれたNishioiさんのサンプルを流用して修正) // 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 //
出力先データセットがカタログされるのであれば、この例のように先行の削除ステップでのDISPにはOLDではなくMODを指定し、VOLを指定しないことがポイント。
データセットが存在していれば削除とアンカタログがなされ、存在していなければ一旦ストレージ・ボリュームに割り振られて削除される(MODはなければ作り、あれば最終レコードに追加する、という特性を持つ)。出力先データセットがカタログされる場合、このサンプルに習えば、初回の実行(旧データセットが無い状態)でも2回目以降(旧データセットがある状態)の実行でも両方正しく動く。
なお、同じDSNの重複記述は修正漏れなどを誘発しやすいので、SETステートメントで実際の名前を割り当てるようにしてある。※SETステートメントは、z/OSでのみ利用可能。MSPにも同様の機能はあるが、プロシージャー内でしか使えなかったはず…
Comment from Nishioi
Time 2011年10月28日 at 12:03
私は先行ステップでDISP=(MOD,DELETE)でやってます。カタログもうまくいきます。(MSPの例)
//XXXXX JOB CLASS=A,MSGCLASS=U,MSGLEVEL=(1,1),REGION=6000K
//DMY1 EXEC PGM=KDJBR14,REGION=6000K
//SYSUT1 DD DSN=XXXXXXXXX,DISP=(MOD,DELETE),
// UNIT=SYSDA,SPACE=(TRK,(1,1))
//DMY2 EXEC PGM=JSECOPY,REGION=6000K
//SYSUT1 DD DSN=YYYYYYYYY,DISP=SHR
//SYSUT2 DD DSN=*.DMY1.SYSUT1,DISP=(NEW,CATLG),
// UNIT=SYSDA,VOL=SER=VVVVVV,SPACE=(CYL,(10,10,30))
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
//