Oracle SQLスクリプトは、大規模言語モデル(LLM)エージェントが生成すると、見た目には完璧に見えても、本番環境で致命的な問題を引き起こすことがあります。230万行に及ぶレガシーなコードベースにおいて、AI駆動のエージェントは、存在しない識別子を頻繁に紛れ込ませていました。例えば、実際の STATUS_CD カラムの代わりに POLICY_STATUS を使用したり、CUSTOMER ではなく存在しない CUSTOMERS テーブルを参照したりといったケースです。

タイポ(打ち間違い)を見つけるためにスクリプトを実行することは、UPDATEDELETE 文においては選択肢に入りません。本番に近いデータセットで実行すると、ロックが発生し、シーケンス番号が消費され、連鎖的な副作用を引き起こす可能性があります。開発者には、データに一切触れることなく、名前や構文を検証する方法が必要です。その答えは、驚くほどシンプルです。Oracleの EXPLAIN PLAN コマンドを、リンティング(静的解析)のステップとして再利用することです。

高速なバリデータとして機能する EXPLAIN PLAN の仕組み

Oracleはステートメントを受け取ると、まずそれをパース(解析)します。パースでは、参照されているすべてのテーブル、カラム、権限が存在するかどうかを確認し、その後、実行計画を構築してシステムテーブルに書き込みます。このコマンドはステートメントを絶対に実行しません。行が変更されることも、トリガーが起動することも、ロックが取得されることもありません。パーサーが未知のオブジェクトに遭遇すると、数ミリ秒以内にエラーを返します。

この挙動により、EXPLAIN PLAN はAIが生成したSQLの完璧な事前チェック(pre-flight check)となります。テーブルやカラムの欠落が即座に報告されるため、人間がスクリプトを目にする前に、生成ループ内で間違いを修正させることができます。

CIパイプラインに組み込んだワークフロー

  1. 分割: 入力されたスクリプトを個々のステートメントに分割する。
  2. 実行: 開発用スキーマに対して EXPLAIN PLAN FOR <statement>実行する。
  3. 収集: Oracleが返すパースエラーを収集する。
  4. フィードバック: エラーをLLMにフィードバックして再試行させる。

実際には、一度再試行するだけで、命名エラーの大部分が解消されます。AIは正しいスキーマを学習し、出力を自動的に調整します。また、エージェントを読み取り専用モードに制限しています。SELECTEXPLAIN PLAN の呼び出しは許可されますが、DDL、DML、および COMMIT はブロックされます。このサンドボックス環境により、AIが構造を調査している間も、データベースが変更されないことが保証されます。

名前チェック以外にも、生成された実行計画は明らかなパフォーマンス上の懸念事項(red flags)を明らかにします。ステートメントが巨大なテーブルに対してフルテーブルスキャンを引き起こす場合、行に触れる前に計画が表示されるため、開発者はインデックスの追加を提案したり、述語(predicate)を書き換えたりする機会を得られます。

この手法の限界

  • 論理的な正しさは検証されない。 正しいカラムを参照していても、誤ったフィルタを適用しているステートメントは、リンティングを通過してしまいます。
  • PL/SQLブロックは対象外。 パーサーは個々のSQLステートメントのみを処理するため、手続き型コードには別の検証パスが必要です。
  • データレベルの検証が欠如している。 リテラル値がカラムのドメインに適合しているか、あるいは外部キー参照が実際に存在するかどうかを、リンティングで判断することはできません。
  • 開発用スキーマのみが対象。 本番環境でのみ発生するエラー(例:開発環境には存在するが、本番環境では名前が変更されているテーブルなど)は、後になるまで検知できません。

これらの欠点は、この手法の有用性を損なうものではありません。単にその適用範囲を定義しているに過ぎません。大半のLLM生成DMLスクリプトにおいて、最も一般的な失敗パターンはタイポや誤ったオブジェクト名であり、それこそが EXPLAIN PLAN が捉えるものなのです。

他のデータベースエンジンへの移植性

同じ原理はOracle以外にも適用できます。PostgreSQLの PREPARE 文や EXPLAIN は、実行せずにクエリをパースできます。SQL Serverには SET PARSEONLY ON があり、実際の処理をスキップしながら構文とオブジェクト名の検証を強制できます。パースと実行を分離しているRDBMSであれば、どのようなものでも軽量なリンティング・ゲートとして活用できます。

まとめ

AIが生成したすべてのSQLステートメントに対して EXPLAIN PLAN(またはそれに相当するもの)を実行することで、データベースのパーサーを、低コストでリスクゼロのリンティング・ゲートへと変えることができます。データが動く前に最も頻繁に起こる命名エラーや構文エラーを捕捉することで、レガシーシステムの安定性を維持しつつ、開発者がLLM支援コーディングによる生産性の向上を享受できるようにします。