はじめに
再利用するためにJCLを汎用的に作ろうと思ったら、可変の文字列をシンボル(変数)にしておいて、先頭部分で変数をセットする、ということをよくやりますよね(変更箇所を一箇所にまとめて、変更の抜け、漏れを無くす、かつ、不要な箇所を変更させないため)。
その際、SYSIN DDに代表されるようなイン・ストリームデータセット(ストリーム内データセット)では"シンボル"が使えない、ということがありましたが、それはもはや過去の話です。
なんとz/OS V2.1からSYSINでもシンボルが使えるようになってました!
なぜいままでこれが出来なかったのか不思議なくらいなのですが、非常にありがたい機能なので何はともあれやってみました。
JCL中のSYSINでのシンボルの使用
JCLその1
マニュアルにサンプルが載ってます。
参考: SYMBOLS パラメーターの例
このサンプルを元に試してみました(サンプルとほぼ同様ですが、Syntaxの確認のため書き方少し変えてます)。
//REALLOC JOB MSGCLASS=X,CLASS=A,NOTIFY=&SYSUID
//*-----------------------------------------------------
//E1 EXPORT SYMLIST=(DSNAME,VOLSER)
//S1 SET DSNAME=CICSSHR.AAA.TEST,VOLSER=Z9CI01
//DEALLIB EXEC PGM=IDCAMS,REGION=300K
//DD1 DD UNIT=3390,DISP=OLD,VOL=SER=&VOLSER
//SYSPRINT DD SYSOUT=*
//SYSIN DD *,SYMBOLS=JCLONLY
DELETE &DSNAME -
NONVSAM PURGE SCRATCH FILE(DD1)
ALLOCATE DSNAME('&DSNAME.') -
UNIT(3390) VOLUME(&VOLSER.) -
NEW CATALOG DSNTYPE(LIBRARY) SPACE(10,10) DIR(5) TRACKS
/*
この例では、データセットのリアロケーションを行っていますが、データセット名とボリューム名をそれぞれDSNAME, VOLSERというシンボルで表しています。
SYSIN DD中で、「&DSNAME.」「&VOLSER.」で示されている箇所です!
ポイントは以下の3つです。
- EXPORTステートメント
- SETステートメント
- SYSIN DDのSYMBOLSパラメーター
SETでシンボルを定義し、EXPORTでSYSINで使用したいシンボルを指定します。
SYSIN DDで、SYMBOLS=JCLONLY を指定します。
(SYMBOLSパラメーターの指定によってシステム上に定義してあるシンボルなども使用できるようですが、詳細はマニュアル参照のこと...)
JOBLOGのSYSPRINTを見てみると、きちんと変数が解釈されて実行されているのがわかります。
IDCAMS SYSTEM SERVICES
DELETE CICSSHR.AAA.TEST -
NONVSAM PURGE SCRATCH FILE(DD1)
IDC0550I ENTRY (A) CICSSHR.AAA.TEST DELETED
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
ALLOCATE DSNAME('CICSSHR.AAA.TEST') -
UNIT(3390) VOLUME(Z9CI01) -
NEW CATALOG DSNTYPE(LIBRARY) SPACE(10,10) DIR(5) TRACKS
IDC0001I FUNCTION COMPLETED, HIGHEST CONDITION CODE WAS 0
IDC0002I IDCAMS PROCESSING COMPLETE. MAXIMUM CONDITION CODE WAS 0
JCLその2
SYMBOLSパラメーターでロギング用のDD指定ができるようなのでやってみました。
//REALLOC JOB MSGCLASS=X,CLASS=A,NOTIFY=&SYSUID
//*-----------------------------------------------------
//E1 EXPORT SYMLIST=(DSNAME,VOLSER)
//S1 SET DSNAME=CICSSHR.AAA.TEST,VOLSER=Z9CI01
//DEALLIB EXEC PGM=IDCAMS,REGION=300K
//DD1 DD UNIT=3390,DISP=OLD,VOL=SER=&VOLSER
//SYSPRINT DD SYSOUT=*
//MESSAGE DD SYSOUT=*
//SYSIN DD *,SYMBOLS=(JCLONLY,MESSAGE)
DELETE &DSNAME -
NONVSAM PURGE SCRATCH FILE(DD1)
ALLOCATE DSNAME('&DSNAME.') -
UNIT(3390) VOLUME(&VOLSER.) -
NEW CATALOG DSNTYPE(LIBRARY) SPACE(10,10) DIR(5) TRACKS
/*
MESSAGE DDを追加し、SYMBOLS=(JCLONLY,MESSAGE)
と指定しています。
JOBLOGのMESSAGE DDの結果を見てみると...
SYSIN : RECORD 1 BEFORE SUBSTITUTION
SYSIN : DELETE &DSNAME -
SYSIN : RECORD 1 AFTER SUBSTITUTION
SYSIN : DELETE CICSSHR.AAA.TEST -
SYSIN : RECORD 2 BEFORE SUBSTITUTION
SYSIN : NONVSAM PURGE SCRATCH FILE(DD1)
SYSIN : RECORD 2 AFTER SUBSTITUTION
SYSIN : NONVSAM PURGE SCRATCH FILE(DD1)
SYSIN : RECORD 3 BEFORE SUBSTITUTION
SYSIN : ALLOCATE DSNAME('&DSNAME.') -
SYSIN : RECORD 3 AFTER SUBSTITUTION
SYSIN : ALLOCATE DSNAME('CICSSHR.AAA.TEST') -
SYSIN : RECORD 4 BEFORE SUBSTITUTION
SYSIN : UNIT(3390) VOLUME(&VOLSER.) -
SYSIN : RECORD 4 AFTER SUBSTITUTION
SYSIN : UNIT(3390) VOLUME(Z9CI01) -
SYSIN : RECORD 5 BEFORE SUBSTITUTION
SYSIN : NEW CATALOG DSNTYPE(LIBRARY) SPACE(10,10) DIR(5) TRACKS
SYSIN : RECORD 5 AFTER SUBSTITUTION
SYSIN : NEW CATALOG DSNTYPE(LIBRARY) SPACE(10,10) DIR(5) TRACKS
ご丁寧に一行ずつシンボルが解釈されている様子が確認できした。
カタログ式プロシージャーでのシンボルの利用
ついでに上のJCLをカタプロ化して、変数部分を引数渡しにしてみます。
//REALLOC PROC PDSNAME=,PVOLSER=
//*-----------------------------------------------------
//E1 EXPORT SYMLIST=(DSNAME,VOLSER)
//S1 SET DSNAME=&PDSNAME.,VOLSER=&PVOLSER.
//DEALLIB EXEC PGM=IDCAMS,REGION=300K
//DD1 DD UNIT=3390,DISP=OLD,VOL=SER=&VOLSER
//SYSPRINT DD SYSOUT=*
//SYSIN DD *,SYMBOLS=MESSAGE
DELETE &DSNAME -
NONVSAM PURGE SCRATCH FILE(DD1)
ALLOCATE DSNAME('&DSNAME.') -
UNIT(3390) VOLUME(&VOLSER.) -
NEW CATALOG DSNTYPE(LIBRARY) SPACE(10,10) DIR(5) TRACKS
/*
この例では分かりやすさのためにプロシージャーの引数は頭に"P"をつけて、PDSNAME、PVOLSERとしていますが、同じ名前でもOKです。
以下のような感じで引数を指定してカタプロ実行できました。
SDSFコマンドによる実行
=> S REALLOC,PDSNAME=CICSSHR.AAA.TEST,PVOLSER=Z9CI01
JCLによる実行
//REALLOCP JOB MSGCLASS=X,CLASS=A,NOTIFY=&SYSUID
//*-----------------------------------------------------
//P1 EXEC REALLOC,PDSNAME=CICSSHR.AAA.TEST,PVOLSER=Z9CI01
/*
素敵です。
この例だと単純なのでアレですが、ミドルウェアなどを扱う際はSYSINで制御することが色々あるのでこれは重宝しそうですね!