JCL入門 ノート

# JCL入門 ノート
## 理由・背景
仕事で学ぶ必要がでたため学習中
DFSORTを中心に取り上げます。
・JCL入門
https://arteceed.info/?p=173
・JCL Tutorial - JCL SORT | JCL SORT Tutorial | JCL SORT Utility | Mainframe JCL SORT Utility | DFSORT
https://www.youtube.com/watch?v=_As64Lzd9gA
・ソート・フィールドの指定
https://www.ibm.com/docs/ja/developer-for-zos/9.5.1?topic=sort-specifying-sorting-field

GSE UK Conference 2019 - Getting Yourself Sorted with DFSORT - Rahul Bajaj
注：スピードを落としたら何とか聞けた。サンプルのところはわからなかったので中断。
https://www.youtube.com/watch?app=desktop&v=TEM12TYLOgM
## JCL用語
JCLは Job Control Languageの略
・使うコンピュータ資源の割り振り。
・プログラムを自動実行させること。
JOB JCLはジョブという単位ごとに作る
EXEC ジョブの中はジョブステップが１つ以上、いくつかある。
DD (Data Definition)ジョブステップごとにDDカードでどういう資源を使うかを定義。
DSN データセット(ファイルとだいたい同じ)
FB はブロック化された固定長 ( fixed-blocked ) 
VB はブロック化された可変長 ( variable-blocked )
キーフィールド（Key field）：データのソートやマージを行う際に使用されるフィールド。ソートの基準となるフィールドです。

### Dfsort 用語
コントロールカード（Control card）：DFSORTの制御情報を含むカードで、DFSORTジョブの操作や処理を指示。SORTコマンドで使用。
レコード（Record）：データの基本的な単位で、通常は行やレコードとして表さる。DFSORTはこれらのレコードをソートおよび処理。
ワークファイル（Work file）：DFSORTが一時的にデータを格納するためのファイル。DFSORTが大容量のデータを処理する際に使用。
アウトプットファイル（Output file）：DFSORT処理の結果として生成されるファイルです。ソートされたデータや処理されたデータがここに書き込る。
シンボリックパラメータ（Symbolic parameter）：DFSORTの制御カード内で使用される変数やパラメータ。これにより、動的な制御や操作が可能になります。
インプットファイル（Input file）：DFSORTの処理対象となる入力ファイル。ソートや処理を行うデータが含まれてる。
ワークスペース（Workspace）：DFSORTがデータを処理するために使用するメモリ領域。高速で効率的な処理を実現。
## 英単語
vice versa 逆に
arithmetic　算術
constsnts　定数
numeric 数値
criteria　基準
## 概要
DFSORT（Data Facility Sort）は、IBMメインフレームコンピュータ上で使用される強力なデータソートユーティリティです。DFSORTは、データのソート、マージ、コピー、レポートの生成など、さまざまなデータ処理タスクを実行するために使用されます。DFSORTは、高速で効率的なソートおよびデータ処理を実現するために最適化されています。

## DFSORT
DFSORTは、以下のような主な機能を提供します：

高速で効率的なソート：大容量のデータセットを高速にソートします。データのキー順にソートするだけでなく、複数のキーに基づいてソートすることもできます。

マージ：複数のソートされたデータセットをマージして1つのソートされたデータセットに統合します。これにより、大規模なデータ処理を効率的に実行できます。

フィルタリングと選択：特定の条件に基づいてデータをフィルタリングしたり、選択したりする機能を提供します。例えば、特定の条件を満たすレコードのみを選択して処理することができます。

データの変換：データの形式を変更したり、特定のフィールドを操作したりする機能を提供します。例えば、日付や数値のフォーマットを変更することができます。

レポート生成：処理されたデータに基づいてカスタムレポートを生成する機能を提供します。レポートの書式や内容はユーザーが定義できます。

DFSORTは、COBOLプログラムやジョブ制御言語（JCL）と統合して使用されることが一般的です。また、DFSORTは高度な機能と柔軟性を提供し、IBMメインフレーム環境でさまざまなデータ処理ニーズに対応します。

## JCLSort Example
XXX JOB
SORT EXEC PGM=SORT
SORTIN DD　入力データ・セット
SORTOUT DD　DFSORT でソートされたデータは、SORTOUT DD ステートメントが示すデータ・セット に入れられる。
SORTWK01 DD　SORTWKdd DD ステートメントは、ソートするレコードの中間ストレージ域に使用するデータ・セットの特性を記述する。また、この特性はデータ・セットの位置も示す。
SORT　FIELDS
### SORT　FIELDS詳細
SORT ステートメントは、PLISRTx への最初の引数
start,length,form,seq
#### form
コード
データ・タイプと長さ
CH
文字 1 から 4096 まで
ZD
ゾーン 10 進数符号付き 1 から 32 まで
PD
パック 10 進符号付き 1 から 32 まで
FI
固定小数点、符号付き 1 から 256 まで
BI
2 進数、符号なし 1 ビットから 4092 バイトまで
FL
浮動小数点、符号付き 1 から 256 まで
全フィールドの合計長は、4092 バイトを超えてはなりません。
#### seq
データが次のようにソートされる順序です。
A
昇順 (つまり、1,2,3,...)
D
降順 (つまり、...,3,2,1)

## Dfsort パラメータ設定例
1. 単純なソート処理
SORT FIELDS=(1,10)
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字でソート処理を行い、出力データセットを作成します。

2. 特定のレコードのみを出力する
SORT FIELDS=(1,10)
INCLUDE=(1,50)
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字でソート処理を行い、1 から 50 番目までのレコードのみを出力データセットを作成します。

3. フィールドの合計値を出力する
SORT FIELDS=(1,10)
SUM FIELDS=(2,5)
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字でソート処理を行い、2 番目と 5 番目のフィールドの合計値を出力データセットに

4. 複数のソートキーを指定する
SORT FIELDS=(1,10),FIELDS=(2,5)
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字と 2 番目から 5 番目の文字でソート処理を行います。

5. 降順ソートを行う
SORT FIELDS=(1,10)
OPTION=DESC
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字で降順ソート処理を行います。

6. 区切り文字を指定する
SORT FIELDS=(1,10)
OPTION=DELIM=','
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字でソート処理を行い、区切り文字をカンマ（,）に指定します。

7. 空白を除去する
SORT FIELDS=(1,10)
OPTION=BLANK=TRIM
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字でソート処理を行い、空白を除去します。

8. 大文字と小文字を区別する
SORT FIELDS=(1,10)
OPTION=CASE=UPPER
INREC RECFM=FB,LRECL=80
OUTREC RECFM=FB,LRECL=80
この例では、入力データセットの最初の 10 文字でソート処理を行い、大文字と小文字を区別します。
## ChatGPT と　BARDの協力を得た例
```
問題1:
以下の名前リストを、名前の昇順でソートしてください。

Jane Doe
John Smith
Alice Brown
Bob White
解答1:
//SORTJOB JOB ...
//SORT EXEC PGM=SORT
//SYSOUT DD SYSOUT=A
//SORTIN DD *
Jane Doe
John Smith
Alice Brown
Bob White
//SORTOUT DD SYSOUT=A
//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
この例では、SORT FIELDS=(1,10,CH,A) で1から10バイト目までをキーにして昇順にソートしています。

問題2:
以下のデータを、重複を除去して名前の昇順でソートしてください。

Jane Doe
Jane Doe
John Smith
Alice Brown
Bob White
解答2:

//SORTJOB JOB ...
//SORT EXEC PGM=SORT
//SYSOUT DD SYSOUT=A
//SORTIN DD *
Jane Doe
Jane Doe
John Smith
Alice Brown
Bob White
//SORTOUT DD SYSOUT=A
//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
  SUM FIELDS=NONE
問題3:
以下の名前と年齢の組み合わせを、名前の昇順でソートしてください。
Jane Doe 30
John Smith 25
Alice Brown 40
Bob White 35
解答3:
bash
//SORTJOB JOB ...
//SORT EXEC PGM=SORT
//SYSOUT DD SYSOUT=A
//SORTIN DD *
Jane Doe 30
John Smith 25
Alice Brown 40
Bob White 35
//SORTOUT DD SYSOUT=A
//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
これらの例では、名前が英字であるため、CH（Character）型を使用しています。データが日本語や他の文字セットを含む場合には、適切なバイト数とエンコーディングを考慮して指定してください
```

### SORT FIELDS： 
ソートの基準となるフィールドを指定します。これは、キーと呼ばれるもので、データをソートする際の比較対象となります。

## DFSORT CONTROL STATEMENT
### SORT FIELDS=(start_position,length,type[,start_position,length,type]...)
start_position: ソート対象フィールドの開始位置
length: ソート対象フィールドの長さ
type: ソートの種類（A：昇順、D：降順）
INCLUDE/OMIT： 特定の条件を満たすレコードを含めるか（INCLUDE）または除外するか（OMIT）を指定します。

### INCLUDE/OMIT COND=(condition)
condition: レコードを選択するための条件式
INREC/OUTREC/OMITREC： 入力レコードの再構築や、出力レコードのフォーマットを指定します。

### INREC/OUTREC/OMITREC FIELDS=(start_position:length,expression,...)
start_position: フィールドの開始位置
length: フィールドの長さ
expression: フィールドの値を計算するための式
SUM： 合計を計算するための制御文。

### SUM FIELDS=(start_position,length[,start_position,length]...)
start_position: 合計を計算するフィールドの開始位置
length: 合計を計算するフィールドの長さ
## INCLUDEの例

INCLUDE 制御文は、DFSORTで特定の条件を満たすレコードを含めるために使用されます。以下は、INCLUDE 制御文の基本的な構造と例です。

基本構造:

INCLUDE COND=(condition)
主なパラメータ:

COND: レコードを選択するための条件式を指定します。
例:

//SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
  INCLUDE COND=(6,3,CH,EQ,C'ABC')
/*
この例では、入力データセットを指定されたソートキー（1バイト目から5バイト目）でソートし、条件に合致するレコードだけを選択しています。具体的な条件は INCLUDE COND=(6,3,CH,EQ,C'ABC') で、これは6バイト目から3バイトのフィールドが 'ABC' と等しい場合にレコードを含めるという意味です。

要するに、INCLUDE 制御文は、指定された条件に合致するレコードを結果に含めるためのものです。条件は様々なものに設定でき、データの選択や抽出に柔軟性を提供します。

## INREC の例
INREC 制御文は、DFSORTで入力レコードの再構築を指定するために使用されます。以下は、INREC 制御文の例です。この例では、入力データセットの2つのフィールドを結合して新しいフィールドを作成します。

//SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
  INREC FIELDS=(1:1,5,6:15,5)
/*
この例では、INREC 制御文の FIELDS パラメータを使用して、新しいレコードのフォーマットを指定しています。具体的には、次のような要素があります：

1:1,5: フィールド1は、元のデータセットの1バイト目から始まる5バイトの文字データです。この部分はそのままコピーされます。

6:15,5: フィールド6は、元のデータセットの15バイト目から始まる5バイトの文字データです。この部分もそのままコピーされます。

この例の実行結果は、入力データセットを指定されたソートキーでソートし、各レコードに新しいフォーマットを適用した結果のデータセットが生成されます。



## OUTRECの例

OUTREC 制御文は、DFSORTで出力レコードのフォーマットを指定するために使用されます。以下は、OUTREC 制御文の基本的な例です。この例では、入力ファイルの先頭に2桁のシーケンス番号を追加して、出力ファイルを生成する場合を考えています。

//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
  OUTREC FIELDS=(1:11,2,ZD,TO=ZD,LENGTH=2,5:1,10)
/*
この例では、OUTREC 制御文の FIELDS パラメータを使用して、新しいレコードのフォーマットを指定しています。具体的には、次のような要素があります：

1:11,2,ZD,TO=ZD,LENGTH=2: フィールド1は、元のデータセットの11バイト目から始まる2バイトの数値データです。ZD はゼロ・ダッシュ符号の数値形式を示し、TO=ZD および LENGTH=2 は出力ファイルにおいても2桁のゼロ・ダッシュ符号数値としてフォーマットすることを指定しています。

5:1,10: フィールド5は、元のデータセットの1バイト目から始まる10バイトの文字データです。この部分はそのままコピーされます。

この例の実行結果は、入力データセットを指定されたソートキーでソートし、各レコードに新しいフォーマットを適用した結果のデータセットが生成されます。

## OUTFILの例
OUTFIL 制御文は、DFSORTで出力ファイルのフォーマットや内容を指定するために使用されます。以下は、OUTFIL 制御文の基本的な構造といくつかの利用例です。

基本構造:

OUTFIL [FNAMES=(output_dataset)] [,OUTREC=(output_record_format)] [,OPTION=(option1, option2, ...)]
主なパラメータ:

FNAMES： 出力データセットの名前を指定します。


FNAMES=(output_dataset)
OUTREC： 出力レコードのフォーマットを指定します。


OUTREC=(output_record_format)
OPTION： 出力のオプションを指定します。例えば、OPTION=STOP を指定すると、指定された条件が満たされると出力が停止します。

例1: OUTFIL を使用して特定の条件を満たすレコードのみを抽出する場合

//SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
  OUTFIL FNAMES=OUTPUT, INCLUDE=(6,3,CH,EQ,C'ABC')
/*
この例では、入力データセットを指定されたソートキーでソートし、条件に合致する（6バイト目から3バイトのフィールドが 'ABC' と等しい）レコードだけを OUTPUT という名前の出力データセットに書き出します。

例2: OUTFIL を使用して特定のフィールドのみを抽出し、新しいフォーマットで出力する場合

//SYSIN DD *
  SORT FIELDS=(1,5,CH,A)
  OUTFIL FNAMES=OUTPUT, OUTREC=(1,5,/,6,3)
/*
この例では、入力データセットを指定されたソートキーでソートし、各レコードから最初の5バイトと次の3バイトを取り出し、それを新しいレコードとして OUTPUT という名前の出力データセットに書き出します。各レコードは改行で区切られます（/）。

OUTFIL 制御文は非常に柔軟であり、異なる要件に対応するために様々なオプションと機能が利用できます。

## JOINKEYSの例


JOINKEYS 制御文は、DFSORTで複数のデータセットを結合するために使用されます。これは、SQLのJOIN操作のように、共通のキーを使用して複数のデータセットを結合するためのものです。以下は、JOINKEYS 制御文の基本的な構造と例です。

基本構造:

JOINKEYS FILE=F1,FIELDS=(start_position,length,type)
JOINKEYS FILE=F2,FIELDS=(start_position,length,type)
[ JOINKEYS FILE=F3,FIELDS=(start_position,length,type) ...]
主なパラメータ:

FILE: 結合対象のファイルを指定します。F1、F2、F3などのラベルが使われます。
FIELDS: 結合キーとなるフィールドを指定します。開始位置、長さ、データ型を指定します。
例:


//SYSIN DD *
  JOINKEYS FILE=F1,FIELDS=(1,5,A)
  JOINKEYS FILE=F2,FIELDS=(1,5,A)
  REFORMAT FIELDS=(F1:1,5,F2:6,10)
  SORT FIELDS=(1,5,A)
/*
この例では、F1とF2という2つのファイルを結合しています。それぞれのファイルにおいて、1バイト目から5バイト目までの範囲をキーとして指定しています。そして、REFORMAT 制御文を使用して、結合した結果のレコードのフォーマットを指定しています。具体的には、新しいフォーマットでは、F1からの最初の5バイトとF2からの次の10バイトを含んでいます。

このジョブは、指定されたキーでF1およびF2をソートし、キーが一致するレコードを結合し、新しいフォーマットで出力ファイルに書き込みます。このようにして、JOINKEYS を使用することで、複数のデータセットをキーに基づいて結合することができます。
## MERGE FIELDSの例
//EXAMP JOB A492,PROGRAMMER
//MERGE EXEC PGM=SORT
//SYSOUT DD SYSOUT=A
//SORTIN01 DD DSN=A123456.MASTER,DISP=SHR
//SORTIN02 DD DSN=A123456.NEW,DISP=SHR
//SORTOUT DD DSN=A123456.SORT.SAMPOUT,DISP=OLD
//SYSIN DD *
 MERGE FIELDS=(110,5,CH,A,1,75,CH,A)
/*

このJCL（Job Control Language）コードは、IBMメインフレーム環境でのDFSORTを使用して、指定された条件で2つのファイルを結合するジョブを定義しています。以下は、提供されたJCLコードの各ステートメントの説明です：

//EXAMP JOB A492,PROGRAMMER: ジョブ定義の開始。ジョブ名は "EXAMP" で、ジョブ番号は "A492" 、作業者は "PROGRAMMER" です。

//MERGE EXEC PGM=SORT: ジョブの実行部分の開始。SORTプログラムを実行することを指定しています。

//SYSOUT DD SYSOUT=A: SORTプログラムの出力をシステム出力にリダイレクトします。

//SORTIN01 DD DSN=A123456.MASTER,DISP=SHR: 入力となる1つ目のファイル（マスターファイル）を指定しています。A123456.MASTERというデータセットが共有モード（SHR）で指定されています。

//SORTIN02 DD DSN=A123456.NEW,DISP=SHR: 入力となる2つ目のファイル（新ファイル）を指定しています。A123456.NEWというデータセットが共有モード（SHR）で指定されています。

//SORTOUT DD DSN=A123456.SORT.SAMPOUT,DISP=OLD: 出力結果を保存するデータセットを指定しています。A123456.SORT.SAMPOUTというデータセットがOLDモードで指定されています。

//SYSIN DD *: SORTプログラムへの入力データを指定するセクションの開始。

MERGE FIELDS=(110,5,CH,A,1,75,CH,A): MERGE操作の指定。110バイト目から5バイトの文字列（キー1）と、1バイト目から75バイトの文字列（キー2）を使って、昇順で2つのファイルをマージ（結合）することを指定しています。

このJCLコードは、DFSORTを使用して2つのファイルを指定された条件で結合し、結果を新しいデータセットに書き込むジョブを定義しています。


## DFSORTの基本的な操作や機能をカバーした問題と答え

```
ソート操作
問題: 次のようなデータがある場合、名前（Name）で昇順にソートしてください。

Name      Age    City
---------------------
John      25     New York
Alice     30     Los Angeles
Bob       28     Chicago
答え: DFSORTの制御カードを使用して以下のようにソートできます。


//SORTJOB JOB ...
//STEP1 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD *
John      25     New York
Alice     30     Los Angeles
Bob       28     Chicago
//SORTOUT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
レポート生成
問題: 次のデータから、都市（City）ごとの人数をカウントしてレポートしてください。

Name      Age    City
---------------------
John      25     New York
Alice     30     Los Angeles
Bob       28     Chicago
John      35     Chicago
答え: DFSORTを使用して以下のようにレポートを生成できます。

//SORTJOB JOB ...
//STEP1 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD *
John      25     New York
Alice     30     Los Angeles
Bob       28     Chicago
John      35     Chicago
//SORTOUT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=(15,15,CH,A)
  OUTFIL FNAMES=OUT1,REMOVECC,
         OUTREC=(1,15,COUNT=(M11,LENGTH=2))
データのマージ
問題: 2つのソートされたファイルをマージして1つのファイルに統合してください。

File1:
1
3
5

File2:
2
4
6
答え: DFSORTを使用して以下のようにマージできます。


//SORTJOB JOB ...
//STEP1 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN1 DD *
1
3
5
//SORTIN2 DD *
2
4
6
//SORTOUT DD SYSOUT=*
//SYSIN DD *
  MERGE FIELDS=(1,1,CH,A)
```
## DFSORTの一般的な操作や機能をカバーした問題と答え

```
問題1: ソートとマージ
以下の2つのファイルを名前（最初の10文字）の昇順でソートし、それらをマージして1つのソート済みファイルにします。

ファイル1:

Jane Doe
John Smith
ファイル2:

mathematica
Alice Brown
Bob White
解答1:

jcl
//SORTMERGE JOB ...
//SORTMERG EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN01 DD *
Jane Doe
John Smith
//SORTIN02 DD *
Alice Brown
Bob White
//SORTOUT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=(1,10,CH,A)
  MERGE FIELDS=(1,10,CH,A)
問題2: 選択と出力
以下のデータから、年齢が30歳以上のレコードを選択し、それを別のファイルに出力してください。

John,25
Alice,30
Bob,35
Jane,28
解答2:

jcl
//SELECTOUT JOB ...
//SELECT EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD *
John,25
Alice,30
Bob,35
Jane,28
//SELECTOUT DD SYSOUT=*
//SYSIN DD *
  SELECT IF=(7,2,ZD,GE,30)
問題3: 集計と統計情報
以下のデータから、売上金額の合計値と平均値を計算してください。

100
200
300
400
解答3:

jcl
//SUMJOB JOB ...
//SUM EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD *
100
200
300
400
//SUMOUT DD SYSOUT=*
//SYSIN DD *
  SUM FIELDS=(1,3,ZD)
これらの問題と解答は、DFSORTの一般的な操作や機能をカバーしています。ソート、マージ、選択、集計など、DFSORTのさまざまな機能を使用してデータを処理することができます。
```