CTS-KB
COBOL 5 / 5

COBOL 本番運用

#COBOL #本番運用 #JCL

対象: GnuCOBOL 4 での開発 + AS/400・メインフレームでの本番運用の理解 基本文法は COBOL 文法基礎、モジュール化は COBOL モジュール設計 を参照


目次

  1. 開発環境と本番環境の違い
  2. 帳票出力
  3. トランザクション処理
  4. エラー処理とリカバリ
  5. AS/400(IBM i)の運用環境
  6. メインフレーム(z/OS)の運用環境
  7. ジョブ管理とスケジューリング
  8. 本番運用の設計パターン

1. 開発環境と本番環境の違い

開発環境(GnuCOBOL + PC/WSL)        本番環境(AS/400 / z/OS)
──────────────────────────────────    ──────────────────────────────────
ファイル = OS上のファイル              ファイル = 物理ファイル/データセット
印刷     = テキストファイル出力        印刷     = スプールファイル → プリンタ
実行     = コマンドラインから直接      実行     = ジョブキューに投入
トランザクション = ファイルロック      トランザクション = COMMIT/ROLLBACK
エラー   = DISPLAY + STOP RUN         エラー   = ジョブログ + 異常終了コード
項目GnuCOBOL(開発)AS/400(本番)z/OS(本番)
ファイルOSファイル物理ファイル(PF)データセット(DD)
帳票出力先テキストファイルスプール(OUTQ)SYSOUT(JES)
ジョブ制御シェルスクリプトCL(Control Language)JCL(Job Control Language)
DBファイル操作DB2/400(SQL可)DB2 z/OS
画面DISPLAY/ACCEPTDDS画面ファイルCICS/BMS
トランザクションファイル単位COMMIT/ROLLBACKCICS/DB2

2. 帳票出力

2.1 COBOL標準の帳票制御

COBOLには帳票出力のための仕組みが言語仕様に組み込まれている。

LINAGE(ページ制御)

FD PRINT-FILE
    LINAGE IS 60 LINES           *> 1ページの印字可能行数
        WITH FOOTING AT 55       *> 55行目以降 = フッタ領域
        LINES AT TOP 3           *> ページ上部の余白
        LINES AT BOTTOM 3.       *> ページ下部の余白
01 PRINT-LINE   PIC X(80).

1ページの構造(LINAGE IS 60, FOOTING AT 55, TOP 3, BOTTOM 3):

LINAGE(ページ制御)

行1-3: LINES AT TOP(余白)

行4: 印字開始 — ヘッダ

行5-54: 明細行(印字可能領域 60行)

行55-63: FOOTING — フッタ領域(ページ合計等)

行64-66: LINES AT BOTTOM(余白)

WRITE ADVANCING(改行・改ページ制御)

*> 1行改行して書く
WRITE PRINT-LINE FROM WS-DETAIL
    AFTER ADVANCING 1 LINE
END-WRITE

*> 3行改行して書く(空行を入れる)
WRITE PRINT-LINE FROM WS-SECTION-HEADER
    AFTER ADVANCING 3 LINES
END-WRITE

*> 改ページして書く
WRITE PRINT-LINE FROM WS-PAGE-HEADER
    AFTER ADVANCING PAGE
END-WRITE

*> 書いてから改行(BEFORE と AFTER の違い)
WRITE PRINT-LINE FROM WS-DATA
    BEFORE ADVANCING 1 LINE    *> 先に書いてから改行
END-WRITE
指定動作
AFTER ADVANCING 1 LINE1行改行してから書く
AFTER ADVANCING n LINESn行改行してから書く
AFTER ADVANCING PAGE改ページしてから書く
BEFORE ADVANCING 1 LINE書いてから1行改行
BEFORE ADVANCING PAGE書いてから改ページ

2.2 帳票の行レイアウト

帳票の各行は WORKING-STORAGE に定義する。FILLER で固定文字列や間隔を埋める。

*> --- ヘッダ行の定義 ---
01 WS-HEADER-1.
    05 FILLER       PIC X(30)  VALUE "=== SALARY REPORT ===".
    05 FILLER       PIC X(30)  VALUE SPACES.
    05 FILLER       PIC X(6)   VALUE "Page: ".
    05 WH-PAGE-NUM  PIC ZZ9.        *> ページ番号(編集項目)
    05 FILLER       PIC X(11)  VALUE SPACES.

*> --- 明細行の定義 ---
01 WS-DETAIL-LINE.
    05 WD-EMP-ID    PIC X(5).
    05 FILLER       PIC X(2)   VALUE SPACES.
    05 WD-EMP-NAME  PIC X(20).
    05 FILLER       PIC X(1)   VALUE SPACE.
    05 WD-BASE      PIC ZZZ,ZZZ,ZZ9.    *> 編集PICTURE(カンマ付き)
    05 WD-OVERTIME  PIC ZZZ,ZZZ,ZZ9.
    05 WD-NET       PIC ZZZ,ZZZ,ZZ9.

*> --- 合計行の定義 ---
01 WS-TOTAL-LINE.
    05 FILLER       PIC X(28)  VALUE "Total:".
    05 WT-TOTAL     PIC ZZZ,ZZZ,ZZZ,ZZ9.
    05 FILLER       PIC X(4)   VALUE " yen".

FILLER の役割:

  • 名前を付ける必要のない固定部分
  • VALUE で固定文字列(ラベル)を定義
  • レイアウト上の「スペーサー」として使う

2.3 ページ制御の実装パターン

*> --- ページ送り判定 ---
*> LINAGE-COUNTER: 現在のページ内の行位置(自動更新)
PERFORM VARYING WS-IDX FROM 1 BY 1
    UNTIL WS-IDX > WS-TOTAL-RECORDS

    *> フッタ領域に達したら改ページ
    IF LINAGE-COUNTER OF PRINT-FILE >= 55
        PERFORM PRINT-FOOTER-PARA
        PERFORM PRINT-HEADER-PARA
    END-IF

    PERFORM PRINT-DETAIL-PARA
END-PERFORM

*> --- ヘッダ印刷 ---
PRINT-HEADER-PARA.
    ADD 1 TO WS-PAGE-NUM
    MOVE WS-PAGE-NUM TO WH-PAGE-NUM
    WRITE PRINT-LINE FROM WS-HEADER-1
        AFTER ADVANCING PAGE
    END-WRITE.

*> --- 明細印刷 ---
PRINT-DETAIL-PARA.
    *> ワーク変数 → 明細行にセット
    MOVE ... TO WD-EMP-ID
    MOVE ... TO WD-BASE
    WRITE PRINT-LINE FROM WS-DETAIL-LINE
        AFTER ADVANCING 1 LINE
    END-WRITE.

実動サンプル: report-print.cob

2.4 AS/400 での印刷

AS/400 では、COBOLの出力はスプールファイルに溜まり、出力キュー(OUTQ)経由でプリンタに送られる。

2.4 AS/400 での印刷

COBOL

WRITE

スプールファイル

(SPLF)

出力キュー

(OUTQ / QPRINT)

物理プリンタ

(PRT01等)

*> AS/400 では ASSIGN TO でプリンタファイルを指定
SELECT PRINT-FILE
    ASSIGN TO PRINTER-QPRINT       *> システムプリンタ
    ORGANIZATION IS SEQUENTIAL.

*> または DDS で定義したプリンタファイル
SELECT PRINT-FILE
    ASSIGN TO FORMATFILE-SALRPT    *> DDS プリンタファイル
    ORGANIZATION IS SEQUENTIAL.

AS/400 のスプール操作(CLコマンド):

WRKSPLF                     スプールファイル一覧を表示
WRKSPLF SELECT(ユーザー)    特定ユーザーのスプールを表示
CHGSPLFA ... OUTQ(QPRINT)  出力キューを変更
DLTSPLF                     スプールファイルを削除
OVRPRTF ... COPIES(3)      印刷部数を変更
OVRPRTF ... HOLD(*YES)     ホールド(すぐに印刷しない)

2.5 メインフレーム(z/OS)での印刷

2.5 メインフレーム(z/OS)での印刷

COBOL

WRITE

SYSOUT

(JES2/JES3)

出力クラスに応じて

ルーティング

//PRINT    DD SYSOUT=A          *> クラスA = 標準プリンタ
//PRINT    DD SYSOUT=A,COPIES=3 *> 3部印刷

3. トランザクション処理

3.1 トランザクションとは

「一連の処理を全て成功させるか、全て取り消すか」を保証する仕組み。

例: 銀行振込
  1. A口座から 10,000円 引き落とし
  2. B口座に 10,000円 入金

  → 1だけ成功して2が失敗したら、お金が消える
  → 両方まとめて成功/失敗を保証する = トランザクション

3.2 COBOL標準の COMMIT / ROLLBACK

*> --- COMMIT: ここまでの変更を確定する ---
WRITE OUT-RECORD
IF WS-FILE-STATUS = "00"
    COMMIT                         *> 変更を確定
ELSE
    ROLLBACK                       *> 変更を全て取り消し
END-IF

*> --- トランザクション境界の設計 ---
*> 「何件ごとにCOMMITするか」が重要
PERFORM VARYING WS-IDX FROM 1 BY 1
    UNTIL WS-EOF
    READ IN-FILE ...
    PERFORM PROCESS-RECORD-PARA
    WRITE OUT-RECORD
    ADD 1 TO WS-COMMIT-COUNT

    *> 100件ごとにCOMMIT(チェックポイント)
    IF WS-COMMIT-COUNT >= 100
        COMMIT
        MOVE 0 TO WS-COMMIT-COUNT
        DISPLAY "Checkpoint: " WS-TOTAL-COUNT " records"
    END-IF
END-PERFORM

*> 残りをCOMMIT
COMMIT

3.3 GnuCOBOL でのトランザクション的な実装

GnuCOBOL にはデータベースの COMMIT/ROLLBACK はないが、ファイル操作で擬似的にトランザクションを実現できる。

*> パターン: 一時ファイルに書き出し → 成功したらリネーム
*>
*> 1. 一時ファイル(work.tmp)に出力
*> 2. 全件成功したら一時ファイルを正式ファイルにリネーム
*> 3. 途中でエラーなら一時ファイルを削除
*>
*> → 正式ファイルは「完全に成功した結果」だけになる

SELECT OUT-FILE
    ASSIGN TO "output.tmp"         *> 一時ファイルに出力
    ORGANIZATION IS LINE SEQUENTIAL
    FILE STATUS IS WS-OUT-STATUS.

*> ... 全件処理後 ...
CLOSE OUT-FILE

IF WS-ERROR-FLAG = "N"
    *> 成功: 一時ファイルを正式ファイルにリネーム
    CALL "CBL_RENAME_FILE"
        USING "output.tmp" "output.dat"
    END-CALL
ELSE
    *> 失敗: 一時ファイルを削除
    CALL "CBL_DELETE_FILE"
        USING "output.tmp"
    END-CALL
END-IF

3.4 AS/400 でのトランザクション

AS/400 では DB2/400 を使い、COMMIT/ROLLBACK が完全にサポートされる。

*> AS/400: ジャーナル管理下のファイルで COMMIT/ROLLBACK が使える
*> 前提: ファイルにジャーナルが開始されていること
*>   STRJRNPF FILE(MYLIB/MYFILE) JRN(MYLIB/MYJOURNAL)

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
    FILE-CONTROL.
        SELECT MASTER-FILE
            ASSIGN TO DATABASE-CUSTMAST
            ORGANIZATION IS INDEXED
            ACCESS MODE IS DYNAMIC
            RECORD KEY IS CM-CUSTOMER-ID
            FILE STATUS IS WS-FILE-STATUS.

*> 特殊名段落で COMMIT 単位を指定
CONFIGURATION SECTION.
    SPECIAL-NAMES.
        COMMITMENT CONTROL IS TRANSACTION-MODE.

PROCEDURE DIVISION.
    OPEN I-O MASTER-FILE

    *> 更新処理
    READ MASTER-FILE KEY IS WS-SEARCH-KEY
    IF WS-FILE-STATUS = "00"
        MOVE WS-NEW-BALANCE TO CM-BALANCE
        REWRITE CM-RECORD
        IF WS-FILE-STATUS = "00"
            COMMIT                  *> 成功 → 確定
        ELSE
            ROLLBACK                *> 失敗 → 取消
        END-IF
    END-IF

AS/400 のジャーナル管理:

ジャーナル = 変更履歴(トランザクションログ)
  CRTJRNRCV → ジャーナルレシーバ作成
  CRTJRN    → ジャーナル作成
  STRJRNPF  → 物理ファイルのジャーナル開始
  ENDJRNPF  → ジャーナル終了

ジャーナルがあると:
  ├─ COMMIT/ROLLBACK が使える
  ├─ 障害時にファイルを復旧できる
  └─ 監査証跡になる

3.5 メインフレーム(z/OS)でのトランザクション

バッチ処理:
  VSAM ファイル + COMMIT/ROLLBACK
  DB2 + SQL の COMMIT/ROLLBACK

オンライン処理:
  CICS がトランザクションマネージャとして制御
  EXEC CICS SYNCPOINT          → COMMIT に相当
  EXEC CICS SYNCPOINT ROLLBACK → ROLLBACK に相当

4. エラー処理とリカバリ

4.1 エラー処理の3層構造

層1: ファイル操作エラー    FILE STATUS でチェック
層2: 業務ロジックエラー    バリデーション(88条件名)
層3: システムエラー        DECLARATIVES / USE AFTER

4.2 層1: FILE STATUS によるエラーハンドリング

77 WS-FILE-STATUS   PIC XX.

OPEN INPUT IN-FILE
EVALUATE WS-FILE-STATUS
    WHEN "00"
        CONTINUE                    *> 正常
    WHEN "35"
        DISPLAY "File not found"
        PERFORM ERROR-EXIT-PARA
    WHEN "39"
        DISPLAY "File attribute mismatch"
        PERFORM ERROR-EXIT-PARA
    WHEN OTHER
        DISPLAY "Unexpected error: " WS-FILE-STATUS
        PERFORM ERROR-EXIT-PARA
END-EVALUATE

*> 読み込み時のエラーチェック
READ IN-FILE
EVALUATE WS-FILE-STATUS
    WHEN "00"
        CONTINUE                    *> 正常
    WHEN "10"
        SET WS-EOF TO TRUE          *> 正常終了(EOF)
    WHEN "23"
        DISPLAY "Record not found"
    WHEN OTHER
        DISPLAY "Read error: " WS-FILE-STATUS
        PERFORM ERROR-EXIT-PARA
END-EVALUATE

必ずチェックすべき FILE STATUS:

コード意味対処
"00"正常処理続行
"10"EOFループ終了(正常)
"22"重複キー業務判断(上書き or スキップ)
"23"レコードなし業務判断(エラー or スキップ)
"35"ファイルなし異常終了
"48"WRITE権限なし異常終了

4.3 層2: 業務ロジックのバリデーション

*> --- 入力チェック段落 ---
*> エラーがあったらエラーテーブルに溜めて、最後にまとめて報告
VALIDATE-PARA.
    MOVE 0 TO WS-ERROR-COUNT

    IF SR-BASE-SALARY = 0
        PERFORM ADD-ERROR-PARA
        MOVE "Base salary is zero" TO WS-ERR-MSG
    END-IF

    IF SR-OVERTIME-HOURS > 80
        PERFORM ADD-ERROR-PARA
        MOVE "Overtime exceeds 80h limit" TO WS-ERR-MSG
    END-IF

    IF SR-EMP-ID = SPACES
        PERFORM ADD-ERROR-PARA
        MOVE "Employee ID is blank" TO WS-ERR-MSG
    END-IF

    IF WS-ERROR-COUNT > 0
        SET SS-ERROR TO TRUE
    END-IF.

ADD-ERROR-PARA.
    ADD 1 TO WS-ERROR-COUNT
    DISPLAY "  WARN: " WS-ERR-MSG.

4.4 層3: DECLARATIVES(宣言的エラー処理)

DECLARATIVES は COBOL の例外ハンドラ。ファイル操作エラーが発生したときに自動的に呼ばれる。

PROCEDURE DIVISION.
DECLARATIVES.
*> --- ファイルエラー時に自動実行される ---
IN-FILE-ERROR SECTION.
    USE AFTER STANDARD ERROR PROCEDURE ON IN-FILE.
IN-FILE-ERROR-PARA.
    DISPLAY "IN-FILE error: " WS-IN-STATUS
    SET WS-FATAL-ERROR TO TRUE.

OUT-FILE-ERROR SECTION.
    USE AFTER STANDARD ERROR PROCEDURE ON OUT-FILE.
OUT-FILE-ERROR-PARA.
    DISPLAY "OUT-FILE error: " WS-OUT-STATUS
    SET WS-FATAL-ERROR TO TRUE.
END DECLARATIVES.

*> --- 通常の処理 ---
MAIN-SECTION SECTION.
MAIN-PARA.
    PERFORM INIT-PARA
    PERFORM PROCESS-PARA UNTIL WS-EOF OR WS-FATAL-ERROR
    PERFORM TERM-PARA
    STOP RUN.

4.5 エラーログの出力

*> --- エラーログファイルへの出力 ---
SELECT ERR-FILE
    ASSIGN TO "error.log"
    ORGANIZATION IS LINE SEQUENTIAL.

FD ERR-FILE.
01 ERR-RECORD   PIC X(120).

*> エラーログ行の構造
01 WS-ERR-LINE.
    05 WE-TIMESTAMP  PIC X(17).     *> YYYY-MM-DD HH:MM:SS
    05 FILLER        PIC X(1) VALUE SPACE.
    05 WE-SEVERITY   PIC X(5).      *> ERROR / WARN
    05 FILLER        PIC X(1) VALUE SPACE.
    05 WE-PROGRAM    PIC X(15).     *> プログラム名
    05 FILLER        PIC X(1) VALUE SPACE.
    05 WE-MESSAGE    PIC X(80).     *> エラーメッセージ

WRITE-ERROR-LOG.
    ACCEPT WE-TIMESTAMP FROM DATE YYYYMMDD
    MOVE "ERROR" TO WE-SEVERITY
    MOVE "CALC-SALARY" TO WE-PROGRAM
    MOVE "Base salary is zero" TO WE-MESSAGE
    WRITE ERR-RECORD FROM WS-ERR-LINE.

4.6 異常終了コード

*> --- 正常終了 ---
MOVE 0 TO RETURN-CODE
STOP RUN.

*> --- 異常終了(エラーあり) ---
MOVE 8 TO RETURN-CODE
STOP RUN.

*> --- 重大エラー ---
MOVE 16 TO RETURN-CODE
STOP RUN.

本番環境では、この RETURN-CODE をジョブ管理システムが監視する。

コード意味ジョブ管理の動作
0正常終了次のステップへ進む
4警告あり(処理は完了)次のステップへ進む(ログを確認)
8エラーあり(一部失敗)後続ステップをスキップ or 条件付き実行
12以上重大エラージョブを即座に中止、オペレータに通知

5. AS/400(IBM i)の運用環境

5.1 AS/400 のアーキテクチャ

5.1 AS/400 のアーキテクチャ

IBM i (OS/400)

アプリケーション

COBOL

プログラム

DB2/400

物理ファイル = テーブル

RPG

プログラム

ジャーナル

(トランザクション)

スプール

(印刷)

ジョブ

スケジューラ

5.2 AS/400 のファイル体系

AS/400 では、ファイル = DB2 テーブル。 COBOLからは通常のファイル操作(READ/WRITE)でアクセスする。

AS/400 のファイル種類:
├─ 物理ファイル(PF)     = テーブル(データの実体)
├─ 論理ファイル(LF)     = ビュー/インデックス
├─ 表示ファイル(DSPF)   = 画面定義
├─ プリンタファイル(PRTF)= 帳票定義
└─ ICFファイル             = 通信
*> AS/400 での SELECT 句
SELECT CUSTOMER-FILE
    ASSIGN TO DATABASE-CUSTMAST       *> 物理ファイル CUSTMAST
    ORGANIZATION IS INDEXED           *> キー付きファイル
    ACCESS MODE IS DYNAMIC            *> 順次/ランダム両対応
    RECORD KEY IS CM-CUSTOMER-ID
    FILE STATUS IS WS-FILE-STATUS.

5.3 AS/400 の CL(Control Language)

CLはAS/400のジョブ制御言語。シェルスクリプト + JCL のような役割。

/* 給与計算バッチジョブの CL プログラム例 */

PGM

    /* ライブラリリストの設定 */
    ADDLIBLE LIB(PAYROLL)

    /* 入力ファイルの存在チェック */
    CHKOBJ OBJ(PAYROLL/EMPMASTER) OBJTYPE(*FILE)
    MONMSG MSGID(CPF9801) EXEC(DO)
        SNDPGMMSG MSG('Employee master file not found') +
            MSGTYPE(*ESCAPE)
    ENDDO

    /* COBOLプログラムの呼び出し */
    CALL PGM(PAYROLL/CALCSALARY) PARM(&PROCESS-DATE)

    /* リターンコードのチェック */
    IF COND(&RETCODE *GT 0) THEN(DO)
        SNDPGMMSG MSG('CALCSALARY ended with errors') +
            MSGTYPE(*ESCAPE)
    ENDDO

    /* 帳票印刷の出力キュー変更 */
    CHGSPLFA FILE(SALRPT) SPLNBR(*LAST) +
        OUTQ(PAYROLL/PRTOUTQ)

ENDPGM

5.4 AS/400 のジョブタイプ

ジョブタイプ説明用途
対話型ジョブ端末からの操作画面入力、問い合わせ
バッチジョブジョブキューに投入月次処理、帳票出力
自動起動ジョブシステム起動時に開始常駐サービス
/* バッチジョブの投入 */
SBMJOB CMD(CALL PGM(CALCSALARY)) +
    JOB(SALARY01) +
    JOBQ(PAYROLL/NIGHTQ) +
    SCDDATE(*CURRENT) SCDTIME('230000')
    /* 23:00に実行 */

6. メインフレーム(z/OS)の運用環境

6.1 z/OS のアーキテクチャ

6.1 z/OS のアーキテクチャ

z/OS

アプリケーション

バッチ COBOL

DB2 / VSAM / QSAM

CICS オンライン

JCL

(ジョブ制御)

JES2/3

(スプール管理)

TWS / OPC

(スケジューラ)

6.2 JCL(Job Control Language)

//SALARY   JOB (ACCT),'SALARY BATCH',CLASS=A,
//         MSGCLASS=X,NOTIFY=&SYSUID
//*
//* ステップ1: 給与計算
//STEP010  EXEC PGM=CALCSALRY
//STEPLIB  DD DSN=PAYROLL.LOAD.LIB,DISP=SHR
//INPUT    DD DSN=PAYROLL.EMP.MASTER,DISP=SHR
//OUTPUT   DD DSN=PAYROLL.SALARY.RESULT,
//         DISP=(NEW,CATLG,DELETE),
//         SPACE=(CYL,(10,5),RLSE),
//         DCB=(RECFM=FB,LRECL=100,BLKSIZE=0)
//ERRLOG   DD DSN=PAYROLL.ERROR.LOG,
//         DISP=(MOD,KEEP,KEEP)
//SYSOUT   DD SYSOUT=*
//REPORT   DD SYSOUT=A              *> プリンタクラスA
//*
//* ステップ2: 正常終了時のみ実行
//STEP020  EXEC PGM=POSTPROC,
//         COND=(8,LT,STEP010)      *> STEP010のRC < 8 なら実行

JCL の DD 文(データ定義):

パラメータ意味
DSN=データセット名(ファイル名)
DISP=(状態,正常時,異常時)ファイルの扱い(NEW/SHR/OLD, CATLG/DELETE/KEEP)
DCB=(RECFM=FB,LRECL=100)レコード形式(FB=固定長ブロック, レコード長100)
SPACE=(CYL,(10,5))領域確保(10シリンダ、増分5)
SYSOUT=A印刷出力(クラスA)
COND=実行条件(前ステップのリターンコードで判定)

6.3 COND パラメータ(ステップ間の制御)

//STEP020  EXEC PGM=REPORT,COND=(0,NE,STEP010)
*> STEP010 の RC が 0 でなければ STEP020 をスキップ
*> → STEP010 が正常終了した場合のみ実行

//STEP030  EXEC PGM=CLEANUP,COND=EVEN
*> 前ステップの成否に関わらず必ず実行
COND 指定意味
COND=(0,NE,STEP010)STEP010のRC != 0 ならスキップ
COND=(8,LT,STEP010)STEP010のRC < 8 なら実行(8以上ならスキップ)
COND=EVEN前ステップが異常終了でも実行
COND=ONLY前ステップが異常終了した場合のみ実行

7. ジョブ管理とスケジューリング

7.1 バッチ処理の時間軸

日次バッチ(毎日):
  22:00  オンライン停止
  22:30  日次締め処理
  23:00  バックアップ
  23:30  帳票出力
  00:00  翌日分のデータ準備
  05:00  オンライン開始

月次バッチ(月末):
  給与計算 → 振込データ作成 → 帳票出力 → 年次更新

年次バッチ(年度末):
  年次決算 → 税務帳票 → マスタ更新

7.2 ジョブネット(依存関係)

7.2 ジョブネット(依存関係)

JOB010

マスタバックアップ

JOB020

勤怠データ取込

JOB080

エラー通知

(JOB030異常終了時)

JOB030

給与計算

JOB040

振込データ作成

JOB050

給与明細帳票

JOB060

銀行送信

JOB070

帳票配布

7.3 GnuCOBOL でのジョブ管理(シェルスクリプト)

#!/bin/bash
# 給与計算バッチジョブ(開発環境版)

LOG_FILE="batch_$(date +%Y%m%d_%H%M%S).log"

echo "=== Salary Batch Start ===" | tee "$LOG_FILE"

# ステップ1: 給与計算
echo "[STEP1] Running calc-salary..." | tee -a "$LOG_FILE"
./salary-main >> "$LOG_FILE" 2>&1
RC=$?

if [ $RC -ne 0 ]; then
    echo "[ERROR] salary-main failed with RC=$RC" | tee -a "$LOG_FILE"
    # エラー通知(メール等)
    exit $RC
fi

# ステップ2: 帳票出力
echo "[STEP2] Running report-print..." | tee -a "$LOG_FILE"
./report-print >> "$LOG_FILE" 2>&1
RC=$?

if [ $RC -ne 0 ]; then
    echo "[ERROR] report-print failed with RC=$RC" | tee -a "$LOG_FILE"
    exit $RC
fi

# ステップ3: 帳票をプリンタに送信(Linux)
echo "[STEP3] Printing report..." | tee -a "$LOG_FILE"
# lpr salary-report.txt          # 実際のプリンタに送る場合
echo "  (Print skipped in dev environment)" | tee -a "$LOG_FILE"

echo "=== Salary Batch Complete ===" | tee -a "$LOG_FILE"
exit 0

8. 本番運用の設計パターン

8.1 バッチ処理の標準構成

*> ==============================================
*> 本番向けバッチプログラムの標準テンプレート
*> ==============================================
IDENTIFICATION DIVISION.
    PROGRAM-ID. BATCH-TEMPLATE.

DATA DIVISION.
WORKING-STORAGE SECTION.
*> --- 処理統計 ---
01 WS-STATS.
    05 WS-READ-COUNT      PIC 9(8) VALUE 0.
    05 WS-WRITE-COUNT     PIC 9(8) VALUE 0.
    05 WS-ERROR-COUNT     PIC 9(8) VALUE 0.
    05 WS-SKIP-COUNT      PIC 9(8) VALUE 0.

*> --- エラー制御 ---
01 WS-ERROR-CONTROL.
    05 WS-MAX-ERRORS      PIC 9(5) VALUE 100.
    05 WS-FATAL-FLAG      PIC X(1) VALUE "N".
       88 WS-FATAL        VALUE "Y".

*> --- チェックポイント ---
01 WS-CHECKPOINT.
    05 WS-COMMIT-INTERVAL PIC 9(5) VALUE 1000.
    05 WS-COMMIT-COUNT    PIC 9(5) VALUE 0.

PROCEDURE DIVISION.
*> DECLARATIVES でファイルエラーを捕捉
DECLARATIVES.
INPUT-ERR SECTION.
    USE AFTER STANDARD ERROR PROCEDURE ON IN-FILE.
    DISPLAY "IN-FILE error: " WS-IN-STATUS.
    SET WS-FATAL TO TRUE.
END DECLARATIVES.

MAIN-SECTION SECTION.
MAIN-PARA.
    PERFORM INIT-PARA
    PERFORM PROCESS-PARA
        UNTIL WS-EOF OR WS-FATAL
    PERFORM TERM-PARA

    *> リターンコード設定
    IF WS-FATAL
        MOVE 16 TO RETURN-CODE
    ELSE IF WS-ERROR-COUNT > 0
        MOVE 8 TO RETURN-CODE
    ELSE
        MOVE 0 TO RETURN-CODE
    END-IF
    STOP RUN.

INIT-PARA.
    OPEN INPUT IN-FILE
    OPEN OUTPUT OUT-FILE
    OPEN OUTPUT ERR-FILE
    DISPLAY "=== Batch Start ===".

PROCESS-PARA.
    READ IN-FILE
        AT END SET WS-EOF TO TRUE
        NOT AT END
            ADD 1 TO WS-READ-COUNT
            PERFORM VALIDATE-PARA
            IF WS-VALID
                PERFORM BUSINESS-LOGIC-PARA
                PERFORM WRITE-OUTPUT-PARA
            ELSE
                PERFORM WRITE-ERROR-PARA
                ADD 1 TO WS-ERROR-COUNT
            END-IF
            *> エラー件数上限チェック
            IF WS-ERROR-COUNT >= WS-MAX-ERRORS
                SET WS-FATAL TO TRUE
                DISPLAY "Max errors exceeded"
            END-IF
    END-READ.

TERM-PARA.
    CLOSE IN-FILE OUT-FILE ERR-FILE
    DISPLAY "=== Batch End ==="
    DISPLAY "  Read:    " WS-READ-COUNT
    DISPLAY "  Written: " WS-WRITE-COUNT
    DISPLAY "  Errors:  " WS-ERROR-COUNT
    DISPLAY "  Skipped: " WS-SKIP-COUNT.

8.2 運用で守るべき原則

1. 冪等性(何度実行しても同じ結果)
   ├─ 再実行可能な設計にする
   ├─ 出力ファイルは上書き(追記しない)
   └─ 「処理済みフラグ」で二重処理を防ぐ

2. チェックポイント(中間セーブ)
   ├─ 大量データ処理では定期的に COMMIT
   ├─ 障害時にチェックポイントから再開できる設計
   └─ DISPLAY で処理件数を定期出力(進捗監視)

3. エラー許容度の設計
   ├─ エラー0件     → RC=0(正常終了)
   ├─ エラーn件以下  → RC=4(警告、処理は完了)
   ├─ エラーn件超過  → RC=8(異常、一部失敗)
   └─ 致命的エラー   → RC=16(即座に中止)

4. ログと監査証跡
   ├─ 処理開始/終了の時刻
   ├─ 入力件数/出力件数/エラー件数
   ├─ エラーの詳細(レコード内容 + 理由)
   └─ リターンコード

8.3 環境ごとの対応表

同じCOBOLプログラムでも、環境によってジョブ制御と運用が異なる。

項目GnuCOBOL(開発)AS/400(本番)z/OS(本番)
ジョブ制御bash スクリプトCL プログラムJCL
ジョブ投入./programSBMJOBSUB / JES
ステップ間制御$? で判定MONMSGCOND=
スケジューラcronAS/400ジョブスケジューラTWS / OPC
帳票出力ファイル → lprスプール → OUTQSYSOUT → JES
トランザクションファイルベースジャーナル + COMMITDB2 / CICS
エラー通知メール / SlackメッセージキューJES MSG / 運用監視
リターンコードRETURN-CODE*ESCAPE MSGCOND CODE

関連記事