対象: GnuCOBOL 4 での開発 + AS/400・メインフレームでの本番運用の理解 基本文法は COBOL 文法基礎、モジュール化は COBOL モジュール設計 を参照
目次
- 開発環境と本番環境の違い
- 帳票出力
- トランザクション処理
- エラー処理とリカバリ
- AS/400(IBM i)の運用環境
- メインフレーム(z/OS)の運用環境
- ジョブ管理とスケジューリング
- 本番運用の設計パターン
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/ACCEPT | DDS画面ファイル | CICS/BMS |
| トランザクション | ファイル単位 | COMMIT/ROLLBACK | CICS/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):
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 LINE | 1行改行してから書く |
AFTER ADVANCING n LINES | n行改行してから書く |
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)経由でプリンタに送られる。
*> 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)での印刷
//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.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.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.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 |
| ジョブ投入 | ./program | SBMJOB | SUB / JES |
| ステップ間制御 | $? で判定 | MONMSG | COND= |
| スケジューラ | cron | AS/400ジョブスケジューラ | TWS / OPC |
| 帳票出力 | ファイル → lpr | スプール → OUTQ | SYSOUT → JES |
| トランザクション | ファイルベース | ジャーナル + COMMIT | DB2 / CICS |
| エラー通知 | メール / Slack | メッセージキュー | JES MSG / 運用監視 |
| リターンコード | RETURN-CODE | *ESCAPE MSG | COND CODE |
関連記事
- RPG 本番運用 — IBM i 上での RPG 本番運用ガイド
- COBOL 文法基礎 — COBOL の基本文法リファレンス
- COBOL モジュール設計 — サブルーチンとモジュール化
- COBOL 業務ロジック実装 — 業務システムの設計パターン