静的解析 vs 動的解析

CRUD図を生成する方法は大きく2つに分かれます。

観点静的解析動的解析
実行環境不要(ソースファイルのみ)DB接続・テスト実行が必要
網羅性全コードパスを解析可能実行されたパスのみ
精度動的SQL は限界あり実行時の実際のSQLを取得
導入コスト低(ソースさえあれば動く)高(テスト環境・DBが必要)
継続的実行CIに組み込みやすいテストスイートが必要

💡 レガシーCOBOL環境では静的解析が現実的

古いCOBOL資産ではテスト環境が存在しないケースも多く、DB接続情報の管理も困難です。静的解析であればソースファイルさえあれば解析できるため、レガシー環境に最適です。

COBOLの静的解析の特徴

Javaの静的解析ではASTパーサー(JavaParser等)が必須でしたが、 COBOLの埋め込みSQLは EXEC SQL〜END-EXEC という 明確な区切りマーカーがあります。 これはJavaのメソッド内に散在するSQL文字列と比較して格段に検出しやすい構造です。

JavaのSQL
文字列リテラル・定数・変数・StringBuilder連結など様々な形で散在。ASTなしでは信頼性の高い抽出は難しい。
COBOLのSQL
EXEC SQL〜END-EXECで必ず囲まれている。正規表現だけでも高精度な抽出が可能。動的SQLのみ例外的に難しい。

正規表現 vs COBOLパーサ

観点正規表現ベースCOBOLパーサ(koopa等)
導入コスト Pythonだけで動作 パーサのセットアップが必要
EXEC SQL抽出精度 マーカーが明確 文法として理解
継続行の処理対応可能(パターン要調整)自動で処理
コメント除外要考慮(7列目の*)自動で処理
固定形式(72文字制限)要考慮自動で処理
動的SQL対応難しい難しい
ポータビリティ 追加依存なし パーサに依存

利用可能なツール比較

koopa
Javaで実装されたCOBOLパーサ。AST生成が可能。依存関係が多く、セットアップコストがやや高い。
GnuCOBOL
COBOLをCに変換するコンパイラ。構文チェックはできるが、CRUD解析用途には不向き。
Python re モジュール
標準ライブラリのみ。EXEC SQL〜END-EXECの抽出には十分な精度を発揮。追加インストール不要。
JSqlParser
抽出後のSQL解析に使用。JavaライブラリだがPython(subprocess経由)やJavaスクリプトで利用可能。

このシリーズの選択と根拠

本シリーズでは Python 正規表現 + JSqlParser の組み合わせを採用します。

  • EXEC SQL〜END-EXEC の明確な区切りにより正規表現で十分な精度が出る
  • Pythonだけで動作するため追加のランタイム依存を最小化できる
  • JSqlParserはSQL解析の実績が豊富で、COBOL由来のSQLにも対応
  • 固定形式・コメント行・継続行の処理をPythonで丁寧に実装することで、パーサと同等の結果を得られる
COBOL — 固定形式の注意点
       *  1〜6列目  : 行番号(シーケンス)
       *  7列目     : 指示子(* でコメント行、- で継続行)
       *  8〜11列目 : Area A(DIVISION・SECTION・段落名)
       *  12〜72列目: Area B(命令文)
       *  73〜80列目: プログラム識別子(無視)

       *--- コメント行の例 ---
      * この行はコメントです

       *--- 継続行の例(7列目が -)---
           EXEC SQL
               SELECT TOKUI-CD, TOKUI-NM, TOKUI-ADDR
      -            TOKUI-TEL
               INTO :WK-CD, :WK-NM, :WK-ADDR, :WK-TEL
               FROM TOKUI
               WHERE TOKUI-CD = :WK-INPUT-CD
           END-EXEC.

静的解析の限界

⚠️ 動的SQLは静的解析の限界

以下のパターンは静的解析で完全には対応できません。

EXECUTE IMMEDIATE による動的SQL実行

② WORKING-STORAGE で組み立てる文字列連結SQL

③ COPY句で別ファイルから取り込まれるSQL(COPY展開が必要)

これらの対処方法はPART 08(まとめ)で解説します。実際のレガシーCOBOLでは全SQLの80〜90%は静的SQLであり、静的解析だけでも十分な価値があります。

次の章では…

PART 03 では実際にPythonで EXEC SQL〜END-EXEC ブロックを抽出するコードを実装します。固定形式・コメント行・継続行をすべて考慮した堅牢な実装を一から作ります。

→ PART 03 — SQL抽出の実装へ