本番データベースへの更新SQLとバッチの変更を、実行前に条件の抜け・全件更新・ロールバックの有無で判定し、レビューの指摘を情報システムの担当へ返す
本番データベースへの更新SQLとバッチの変更を、実行前に読み、条件の抜け・全件更新・戻し方の不備を観点ごとに判定します。指摘と直し方を付けて、情報システムの担当へ返します。
- 生成AI
- ChatGPT/Claude/Gemini
- 連携・自動化
- Google Apps Script/Python
- 対象業界
- IT・SaaS/保険/小売/金融
- 対象部門
- 情報システム
- 対象業務
- 内容確認・チェック
- 主な課題
- 人手が足りない/属人化している/確認ミスが多い
- AIで行う処理
- 判定
- 主な効果
- 品質標準化/属人化解消/工数削減
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- API連携(中)
- 人間の確認
- 必須
01導入前 / 導入後の業務フロー
- 申請者が変更管理のチケットを作り、SQLファイルと申請票を添付してレビューを依頼する
- レビュー担当がSQLを開き、`UPDATE` と `DELETE` に `WHERE` 句があるかを確かめる
- `WHERE` 句の条件が、申請票の目的と合っているかを読む
- 検証環境で `SELECT COUNT(*)` を同じ条件で流し、見込み件数と比べる
- トランザクションの書き方、`COMMIT` の位置、戻し方の手順を確かめる
- 指摘をチケットに書き、申請者に返す
- 直ったものを再度読み、承認して実行の担当に回す
- 人申請者がチケットにSQLファイルと申請票を添付し、ステータスを「レビュー依頼」にする
- 自動ステータスの変更をきっかけに、レビューのスクリプトがSQLと申請票を取り出す
- 自動スクリプトがSQLを構文解析し、`WHERE` の有無、トランザクションの有無、対象テーブルを機械で確かめる
- 自動検証環境で、同じ条件の件数を数える。更新はトランザクションの中で流して件数を取り、必ず `ROLLBACK` する
- 自動Claude API が、SQL・申請票・機械の確認結果・件数を読み、観点ごとに判定して指摘を書く
- 自動観点ごとの結果から、`approve_candidate` / `needs_fix` / `needs_dba` を規則で決め、チケットにコメントする
- 人レビュー担当が判定と指摘を確かめ、申請者へ返すか、承認するかを決める
- 人`needs_dba` のものは、データベースに詳しい担当が読む
- 人承認されたものを、実行の担当が本番で流す
各工程の詳しい説明を読む
- 申請者が変更管理のチケットを作り、SQLファイルと申請票を添付してレビューを依頼する
- レビュー担当がSQLを開き、
UPDATEとDELETEにWHERE句があるかを確かめる WHERE句の条件が、申請票の目的と合っているかを読む- 検証環境で
SELECT COUNT(*)を同じ条件で流し、見込み件数と比べる - トランザクションの書き方、
COMMITの位置、戻し方の手順を確かめる - 指摘をチケットに書き、申請者に返す
- 直ったものを再度読み、承認して実行の担当に回す
(a)WHERE があるだけで安心してしまう。 全件更新は誰でも気をつけますが、条件が1つ足りないSQLは、WHERE がある分だけ見落とされます。 会員システムで、店舗の条件はあるのに会員の区分の条件が抜けていれば、対象外の会員まで書き換わります。
(b)結合を使う更新は読み方を知らないと危ない。 PostgreSQL の UPDATE ... FROM は、対象の1行に結合先の行が複数当たると、どの行で更新されるかが予測できないと公式の文書が注意しています。書いた本人も気づいていないことが多く、レビューする側が知っているかどうかで結果が変わります。
(c)戻し方が具体的でない。 「バックアップから戻す」では、どの時点のバックアップから、どのテーブルの、どの行を戻すのかが分かりません。実際に戻す段になって、他の更新まで巻き戻すことになります。
(d)件数の確認が人によって違う。 ある担当は必ず検証環境で数え、別の担当は申請票の見込み件数を信じて通します。同じ申請でも、誰が見たかで確認の深さが違います。
- 【人】 申請者がチケットにSQLファイルと申請票を添付し、ステータスを「レビュー依頼」にする
- 【自動】 ステータスの変更をきっかけに、レビューのスクリプトがSQLと申請票を取り出す
- 【自動】 スクリプトがSQLを構文解析し、
WHEREの有無、トランザクションの有無、対象テーブルを機械で確かめる - 【自動】 検証環境で、同じ条件の件数を数える。更新はトランザクションの中で流して件数を取り、必ず
ROLLBACKする - 【自動】 Claude API が、SQL・申請票・機械の確認結果・件数を読み、観点ごとに判定して指摘を書く
- 【自動】 観点ごとの結果から、
approve_candidate/needs_fix/needs_dbaを規則で決め、チケットにコメントする - 【人】 レビュー担当が判定と指摘を確かめ、申請者へ返すか、承認するかを決める
- 【人】
needs_dbaのものは、データベースに詳しい担当が読む - 【人】 承認されたものを、実行の担当が本番で流す
4番目が、この設計の土台です。 件数は推測ではなく、検証環境で実際に数えた数字です。 申請票の見込み件数と食い違えば、それだけで指摘になります。
7番目を省かないでください。 AIが approve_candidate を出しても、承認するのは人です。 この構成は承認の候補を絞るためのもので、承認の権限を持ちません。
02今回想定するシステム構成
申請者(利用部門・保守ベンダー・バッチの担当) │ SQLファイル+申請票(目的/対象テーブル/見込み件数/実行日時/戻し方) ▼【トリガー】チケットのステータスが「レビュー依頼」 レビューのスクリプト(Python) ├──▶ 構文解析:WHERE の有無、トランザクション、対象テーブル、結合 ├──▶ 検証環境(本番と同じ構造):件数を数える/更新は流して ROLLBACK ▼ Claude API ── 観点ごとの判定と指摘 │ ① 条件の抜け ② 件数の食い違い ③ 結合の重複 ④ 戻し方の具体性 │ ⑤ トランザクション ⑥ 実行時間と時間帯 ⑦ バッチの変更の影響 ▼ レビューのスクリプト ── verdict を規則で決め、チケットにコメント ▼ 【人】レビュー担当 → 承認 or 差し戻し └──▶ needs_dba はデータベースに詳しい担当へ ▼ 【人】実行の担当が本番で実行
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 処理 | Claude API(観点ごとの判定、指摘と直し方の下書き) | OpenAI API、Gemini API |
| 連携 | Python(チケットの読み書き、構文解析、検証環境での件数の取得、規則による判定) | Google Apps Script |
| データベース | PostgreSQL(基幹)、MySQL(会員)の検証環境 | 本番と同じ構造の別の検証環境 |
| 申請の受付 | 既存の変更管理のチケット | 共有フォルダとフォーム |
本番のデータベースは、この構成の図に出てきません。 スクリプトがつなぐのは検証環境だけで、本番の接続情報はスクリプトに持たせません。 実行の担当が、承認されたSQLを従来どおりの手順で流します。
判定の受け取り方は、Claude API の構造化出力です。 リクエストの output_config.format に type: "json_schema" とスキーマを渡すと、返答がそのスキーマに沿ったJSONになります。観点ごとの判定を enum で固定できるので、6番目の規則をスクリプトで書けます。 ただし数値の minimum・maximum のような制約には対応していないため、件数の比較はスクリプトで行います。
検証環境での件数の数え方は、データベースの仕様に合わせます。 PostgreSQL の UPDATE は成功すると UPDATE count の形で更新した行数を返し、0件でもエラーにはなりません。 また RETURNING で更新前の値(OLD)と更新後の値(NEW)を返せるので、検証環境で流したときの変更前後をそのまま記録できます。 0件が誤りと扱われないことは、件数をスクリプトで必ず比べる理由でもあります。
03どうやって実装するのか
処理の起点を決める
チケットのステータスが「レビュー依頼」になったことを起点にします。 SQLファイルの添付だけを起点にすると、書きかけのファイルを添付し直すたびにレビューが走ります。申請者が「見てください」と意思表示した時点から動かします。
レビューの結果をチケットにコメントしたら、ステータスを「一次レビュー済み」に変えます。人がレビューを始めるのはこのステータスからです。 申請者がSQLを直して再び「レビュー依頼」にすると、もう一度動きます。
実行日時の直前の申請は、別の扱いにします。 申請票の実行日時まで24時間を切っているものは、判定に加えて、レビュー担当へ直接通知します。AIの判定を待つあいだに実行の時刻が来ることを防ぎます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| SQLファイル | 更新・削除・挿入の文、トランザクションの書き方 | チケットの添付 |
| バッチの変更の差分 | 変更前後のSQLや設定、実行の時間帯 | チケットの添付(差分のファイル) |
| 申請票 | 目的、対象テーブル、見込み件数、実行日時、戻し方 | チケットの項目 |
| 構文解析の結果 | 文の種類、WHERE の有無と条件の列、結合、トランザクションの有無 | レビューのスクリプト |
| 件数の結果 | 条件に当たる件数、検証環境で流したときの更新件数、変更前後の値の見本 | 検証環境 |
| テーブルの定義 | 列、主キー、一意の制約、テナントや店舗の列、件数の目安 | 検証環境の定義情報 |
| レビューの基準 | 必須とする書き方、時間帯の決まり、件数の閾値 | 情報システム部で定める基準書 |
質を決めるのは、テーブルの定義とレビューの基準です。 テーブルの定義が無いと、AIは「テナントの列があるのに条件に入っていない」ことに気づけません。主キーと、絞り込みに必ず入れるべき列を、テーブルごとに一覧で持たせます。
レビューの基準は、AIの物差しになります。 「1万件を超える更新は夜間に限る」「DELETE は論理削除で代える」といった決まりが書かれていないと、判定が担当者の暗黙の基準から、AIの一般論に置き換わるだけです。
データの取得方法を決める
| 取るもの | どこから | 何に使うか |
|---|---|---|
| SQLと申請票 | チケットのAPI(添付と項目) | 判定の対象 |
| 構文解析の結果 | スクリプトの解析 | 機械で決まる指摘と、AIへの材料 |
| 条件に当たる件数 | 検証環境で SELECT COUNT(*) を同じ条件で流す | 見込み件数との比較 |
| 更新件数と変更前後 | 検証環境でトランザクションの中で流し、ROLLBACK する | 結合の重複や、想定外の行の検出 |
| テーブルの定義 | 検証環境の定義情報 | 主キー、一意の制約、絞り込みの列 |
検証環境のデータは、本番に近い件数と分布である必要があります。 件数が本番の1割しかない検証環境で数えても、見込み件数との食い違いを見つけられません。 検証環境をいつの時点の本番から作ったかを、判定と一緒に記録します。
結合を含む更新では、更新件数と、条件に当たる対象の行の数を両方取ります。 PostgreSQL の公式の文書は、FROM を使う更新で対象の1行が結合先の複数の行と結び付く場合、どの行で更新されるかは容易に予測できないとし、副問い合わせで参照するほうが安全だとしています。結合の結果の行数が対象の行数より多ければ、その時点で重複があります。
AIへ渡す前に整形する
- ファイルの確認 … SQLファイルの文字コードと改行をそろえ、複数の文を1文ずつに分けます
- 構文解析 … 文の種類(
UPDATE/DELETE/INSERT/ALTERなど)、対象テーブル、WHEREの条件の列、結合、LIMITを取り出します - 機械で決まる指摘 …
WHEREの無いUPDATE・DELETE、トランザクションの無い複数文、COMMITの前に件数の確認が無いことを、この段で指摘にします - 検証環境での件数 … 同じ条件で件数を数え、更新はトランザクションの中で流して件数と変更前後の見本を取り、
ROLLBACKします - テーブルの定義の取り出し … 対象テーブルの主キー、一意の制約、絞り込みに必須の列を一覧から引きます
- 申請票の正規化 … 見込み件数を数値にし、実行日時を時刻にそろえます
- 秘密の情報の除去 … SQLの中に会員の氏名や電話番号が直書きされていれば、伏せ字にしてからAIに渡します
3番目をAIの前に置くのが大事です。 WHERE の無い更新は、AIに聞かなくても分かります。機械で決まるものは機械で決め、AIの判定と混ぜません。 混ぜると、AIが見落としたときに一緒に抜けます。
4番目の ROLLBACK は、スクリプトの中で例外が起きても必ず実行されるように書きます。 検証環境とはいえ、流しっぱなしにすると次の申請の件数がずれます。MySQL の検証環境には、--safe-updates の設定も重ねます。 この設定では、キーの条件も LIMIT も無い UPDATE と DELETE が拒否されるので、スクリプトの誤りで全件を書き換える経路を1つ減らせます。
AIに処理させる
させるのは、SQLと申請票と機械の確認結果を読み、7つの観点ごとに問題があるかを判定し、根拠の箇所と直し方を書き出すことだけです。
| 観点 | 判定の仕方 | 判断できないときの扱い |
|---|---|---|
| 条件の抜け | 目的とテーブルの定義に対して、絞り込みの列が足りないか | 目的が曖昧なら unknown |
| 件数の食い違い | 見込み件数と、検証環境の件数が大きく違う理由が説明できるか | 件数が取れなければ unknown |
| 結合の重複 | 更新件数と対象の行数の差、結合の条件 | 結合が複雑なら unknown |
| 戻し方の具体性 | 戻す対象の行・時点・手順が書かれているか | ― |
| トランザクション | 開始・件数の確認・確定の順になっているか | ― |
| 実行時間と時間帯 | 件数とテーブルの規模に対して、実行の時間帯が基準に合うか | 規模が分からなければ unknown |
| バッチの変更の影響 | 差分で対象テーブル・条件・時間帯が変わったか | 差分が無ければ not_applicable |
右端の列が、この構成の安全装置です。 判断がつかないものを「問題なし」にせず、unknown として人に回します。
| させないこと | 理由 |
|---|---|
| SQLの実行、本番への接続 | AIは文面と数字だけを見る |
| 影響件数の推測 | 検証環境で数えた数字を使う |
| 承認の判断 | 承認の権限は人が持つ |
| SQLの書き直しの確定 | 直し方は案。書き直すのは申請者 |
| 業務上の目的の妥当性の判断 | データを直すべきかは利用部門が決める |
2行目がいちばん起きやすい失敗です。 件数を渡さずにSQLだけを見せると、AIは「数百件程度と見込まれる」と書きます。もっともらしいだけに、数えた数字と取り違えられます。
指示内容を固定する
あなたは情報システム部で、本番データベースへの変更を実行前にレビューする担当です。
次の材料だけを根拠に、7つの観点ごとに判定してください。SQLを実行した前提で書かないでください。
【観点】
1. missing_condition ... 目的とテーブルの定義に対して、絞り込みの条件が足りない
2. count_mismatch ...... 見込み件数と検証環境の件数の差に、説明がつかない
3. join_duplication .... 結合で、対象の1行に複数の行が当たっている
4. rollback_plan ....... 戻す対象の行・時点・手順が具体的に書かれていない
5. transaction ......... 開始→件数の確認→確定の順になっていない
6. timing .............. 件数と規模に対して、実行の時間帯が基準に合わない
7. batch_change ........ バッチの差分で、対象・条件・時間帯が変わっている
【result の選び方】
- issue ........... 問題がある
- ok .............. 問題がない
- unknown ......... 材料が足りず判断できない
- not_applicable .. その観点が当てはまらない
迷ったときに ok を選ばないでください。
【厳守事項】
- 件数は【検証環境の件数】の値だけを使ってください。件数を推測しないでください。
- 【機械の確認結果】にある指摘を繰り返さないでください。それ以外の点を見てください。
- 条件の抜けは、【テーブルの定義】の「絞り込みに必須の列」と照らしてください。
- 「バックアップから戻す」だけの戻し方は issue です。時点・対象の行・手順が要ります。
- evidence には、根拠にしたSQLの行か申請票の文をそのまま写してください。
- fix には、直し方の方針を書いてください。SQLの全文を書き直さないでください。
- 承認してよいか、実行してよいかは書かないでください。
- 業務上、そのデータを直すべきかどうかは判断しないでください。
【申請票】{request}
【SQL】{sql}
【バッチの差分】{batch_diff}
【機械の確認結果】{static_checks}
【検証環境の件数】{counts}
【テーブルの定義】{table_defs}
【レビューの基準】{review_rules}
「件数を推測しない」を明記しないと、count_mismatch は役に立ちません。 推測した件数と見込み件数を比べて「整合している」と書けば、検証環境で数えた意味がなくなります。
「機械の確認結果を繰り返さない」も効きます。 書かないと、AIは WHERE の有無の話から書き始め、本当に読んでほしい条件の抜けの指摘が短くなります。
出力形式を固定する
次の形のJSONで受け取ります。
{
"ticket_id": "",
"statements": 0,
"checks": [
{ "aspect": "missing_condition",
"result": "issue | ok | unknown | not_applicable",
"severity": "high | medium | low",
"evidence": "", "fix": "" }
],
"questions_for_requester": [""],
"verdict": "approve_candidate | needs_fix | needs_dba"
}
checks には7つの観点を1つずつ並べます。verdict はAIに出させず、スクリプトが機械の確認結果と checks から規則で埋めます。
| 条件 | verdict |
|---|---|
| 機械の確認で指摘がある | needs_fix(AIの結果にかかわらず) |
issue が1つ以上 | needs_fix |
join_duplication が issue か unknown | needs_dba |
unknown が1つ以上 | needs_dba |
すべてが ok か not_applicable | approve_candidate |
1つ目の理由は、機械の指摘とAIの指摘を同じ一覧に並べられることです。 レビュー担当は、チケットのコメントを1か所読めば済みます。
2つ目は、verdict を規則にしておけることです。 レビューの基準が変わっても、直すのは規則だけです。結合を含む更新を必ず詳しい担当へ回す、という決まりも規則で書けます。
3つ目は、questions_for_requester で差し戻しが速くなることです。 「この条件で店舗の区分を絞らないのは意図どおりか」のように、申請者に聞くべきことを先に並べます。 指摘と質問を分けておくと、申請者が答えるだけで済む差し戻しが増えます。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 変更管理のチケット | API(添付の取得、コメントの書き込み、ステータスの変更) | 申請の受け取りと、判定の返却 |
| 検証環境のデータベース | 読み取りと、トランザクション内での更新と ROLLBACK | 件数と変更前後の見本 |
| Claude API | API呼び出し(構造化出力) | 7つの観点の判定と指摘 |
| 社内チャット | 通知 | needs_dba と、実行日時が近いもの |
本番のデータベースにはつなぎません。 スクリプトが持つのは検証環境の接続情報だけで、検証環境のアカウントにも、本番への経路を与えません。
チケットのSQLファイルも書き換えません。 直し方はコメントに書くだけで、直すのは申請者です。 AIの直し方をそのまま本番に流す経路を作らないためです。
人が確認する
人が全件を見ます。ただし見る深さが変わります。 approve_candidate は指摘が無いことと件数を確かめて承認し、needs_fix と needs_dba は指摘の根拠を読みます。
- 実行日時の近いものを先に見る … 24時間以内のものから処理します
needs_dbaを詳しい担当へ回す … 結合を含む更新と、判断できなかったものですneeds_fixの根拠を確かめる …evidenceを読み、指摘が正しいかを確かめて申請者へ返しますapprove_candidateを承認する … 件数と戻し方を目で確かめてから承認します- 判定を覆したら記録する … どの観点を、どちらに変えたかを残します
4番目の確認は、短くても省きません。 AIが問題なしとした申請を、人が承認せずに流す運用にすると、この構成は承認の仕組みではなく、承認を飛ばす仕組みになります。
目標は、150件をならして1件8分です。 approve_candidate は数分、needs_fix は10分前後、needs_dba はそれ以上かかります。詳しい2名が読むのは needs_dba だけになり、ほかの2名でも残りを回せることが、この構成のもう一つの狙いです。
例外に対処する
| 起きること | 対応 |
|---|---|
| SQLファイルが添付されていない | 判定せず、申請者へ差し戻す |
| 構文解析ができない(方言、ストアドプロシージャ) | 機械の確認を飛ばしたことを明記し、needs_dba にする |
| 検証環境に対象テーブルが無い・構造が違う | 件数を取らずに unknown。検証環境の更新を担当へ依頼 |
| 検証環境での件数の取得が時間切れ | 件数を取れなかったと明記し、needs_dba |
ROLLBACK に失敗した | 処理を止め、検証環境の担当へ通知。次の申請を流さない |
| DDL(テーブルの変更)が含まれる | 判定は行うが、必ず needs_dba にする |
| 実行日時まで24時間を切っている | 判定と並行して担当へ直接通知 |
| API が応答しない・形が崩れる | 機械の確認結果だけをコメントし、AIの判定は再実行 |
上の3行が大半を占めます。 どれもAIの問題ではなく、申請の出し方と検証環境のそろい方の問題です。 検証環境を本番と同じ構造に保つことが、判定の精度を上げるより効きます。
5行目は起きる頻度は低いですが、止め方を決めておきます。 検証環境に流しっぱなしの更新が残ると、次の申請の件数がずれ、正しい申請を食い違いとして返すことになります。
記録を残す
- 申請票、SQLファイル、バッチの差分と、受け取った日時
- 構文解析の結果と、機械で決まった指摘
- 検証環境の件数と変更前後の見本、検証環境を作った時点
- Claude API が返したJSONの全文と、スクリプトが決めた
verdict - 人が判定を覆した記録と、承認した人・承認した日時
- 本番で実行した日時と、実行後に返った件数
3つ目で「検証環境を作った時点」を残すのは、件数の意味が時点で変わるためです。 1か月前の本番から作った検証環境で数えた件数は、本番で流したときの件数と違って当然です。 差が出たときに、どちらが古いのかを後から説明できます。
最後の行は、実行後の照合に使います。 本番で返った件数を検証環境の件数と比べ、大きく違えば、その場で戻し方の手順に入れるかを判断します。
04実装レベルの3段階
最小構成では件数がさばけません。 1件ずつ貼るので、150件には使えません。読めるかを確かめる段階です。 半自動化で、1件20分が12分程度になります。 件数の取得と機械の確認は自動になりますが、チケットからの取り出しとコメントの書き込みが手作業で残ります。本格構成で8分になり、この段階が本記事の想定です。 差が大きいのは、振り分けと差し戻しのやり取りが、1件ずつの手作業だからです。 段階を飛ばさないでください。 半自動化の一覧を1か月見ると、条件の抜けが多いテーブルと、戻し方が書かれない申請者が分かります。テーブルの定義と申請票の書き方を直してから本格構成に進むほうが、unknown が減ります。
05工数削減シミュレーション
導入後 150件 × 8分 ÷ 60 = 20 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 利用部門の依頼やベンダーの保守で、本番データベースへのデータ修正のSQLやバッチの変更が毎月数十件以上申請され、情報システム部門が実行前にレビューしている会社。レビューができる人が1〜2名に限られ、その人の不在時に申請が止まる場合。検証環境に本番と同じ構造のデータベースを用意できる場合。
- 本番データベースの更新が月に数件で、担当者が全件を丁寧に読める場合。データの修正をすべて業務アプリの画面から行い、SQLを直接流す運用が無い場合。検証環境が無く、件数の確認を本番でしか行えない場合。なお、実行してよいかの承認と、実行そのものは、この構成では代替できません。
07最小構成で試す方法
- 先月レビューした申請から30件を選ぶ(うち数件は、差し戻したものと、実行後に問題が出たものを入れる)
- その30件について、当時の指摘と検証環境の件数を取り出す
- レビューの基準とテーブルの定義を、対象テーブルの分だけ1枚にまとめる
- 手元のAIサービスの画面に、基準・定義・申請票・SQL・件数を貼り付ける(会員の個人情報は伏せる)
- 「7つの観点ごとに判定する。件数は渡した値だけを使う。承認の可否は書かない」と指示する
- 出てきた判定を、当時の指摘と突き合わせる
30件は必ずやってください。 スクリプトを組む前に、「申請の意図との食い違いを読めるか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 当時の指摘と同じ点が出た | 構文解析と検証環境の件数の自動化に進む |
| 件数を推測して書いた | 指示の書き方で直る。構成は有効 |
| 条件の抜けを見落とす | テーブルの定義に絞り込みに必須の列が無い。 一覧の整備が先 |
実行後に問題が出た申請は、とくに丁寧に見てください。 当時のレビューで通ったものをAIが issue と判定できるか、unknown で人に回せるかが、この構成の価値を決めます。どちらでもなく ok と出たなら、渡した材料のどこかが足りていません。
3行目が出たら、それが最初の成果です。 「この表は店舗の条件を必ず入れる」という知識が、詳しい担当の頭の中にしか無かったことが分かります。一覧に書き出せば、AIだけでなく、ほかの担当者も同じ見方ができます。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| AIが件数を推測して「整合」と書く | 件数は検証環境で数えた値だけを渡し、推測を禁じる |
WHERE の有無の話ばかりになる | 機械の確認を先に済ませ、繰り返さないよう指示する |
| 条件の抜けを見落とす | テーブルごとに絞り込みに必須の列を一覧で渡す |
| 結合の重複に気づかない | 更新件数と対象の行数を両方取り、差があれば needs_dba |
| 0件の更新が問題なしに見える | PostgreSQL では0件はエラーにならない。見込み件数と必ず比べる |
検証環境の ROLLBACK 漏れ | 例外時も必ず戻す書き方にし、失敗したら次を流さない |
| 検証環境が古くて件数が合わない | 作った時点を記録し、定期的に作り直す |
| 「バックアップから戻す」が通る | 時点・対象の行・手順が無ければ issue と指示する |
| AIの直し方がそのまま流される | 直し方は方針まで。書き直しは申請者、承認は人 |
| 承認を省く運用に流れる | approve_candidate も人が承認する |
上の2行が、作り始めて最初に当たる壁です。 どちらもAIに「何を見ないか」を伝えていないことから起きます。件数と機械の確認を先に済ませ、AIには残りだけを読ませる、という分担が決まると安定します。
下の2行は、運用を始めてから効いてきます。 判定が当たり続けると、人の確認が形だけになります。承認を人が持つことを、仕組みとしても運用としても崩さないでください。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: SQLの文面、テーブルの定義、検証環境の件数と変更前後の見本、そしてSQLに直書きされた会員の情報です。
- 本番の接続情報をスクリプトに持たせない … つなぐのは検証環境だけです。AIにも、スクリプトにも、本番への経路を与えません
- 検証環境のデータを伏せる … 検証環境が本番のコピーなら、個人情報を含みます。AIに渡すのは件数と、必要な列だけの見本に限り、氏名や連絡先は伏せます
- SQLの直書きの値を伏せる … 会員番号や電話番号が条件に直書きされていれば、伏せ字にしてから渡します
- この構成は承認を代替しません … 実行してよいかを決めるのは人で、承認の記録を残します
- テーブルの定義を外へ出しすぎない … 判定に要るのは対象テーブルの定義だけです。データベース全体の構造を毎回渡しません
- 判定の記録を監査に使えるようにする … 誰が、どの判定を見て承認したかを残します
誤りが起きた場合のリスクは、危ない更新を通してしまうことと、正しい申請を止めて業務を遅らせることの2つです。 前者は unknown を ok に倒すと起き、後者は検証環境が古いと起きます。前者は設計で防ぎ、後者は検証環境の運用で防ぎます。
10まず何から始めるか
1週目:テーブルの一覧を作る
更新の申請が多いテーブルから、主キー、一意の制約、絞り込みに必須の列を一覧にします。全テーブルを一度に埋める必要はありません。申請の多い上位20テーブルで、申請の大半を占めます。
2週目:30件で試す
先月の申請から30件を選び、手元のAIサービスで7つの観点を判定させます。当時の指摘と突き合わせ、件数を推測していないか、条件の抜けを拾えているかを最優先で見ます。
3週目:レビューの基準と申請票を直す
時間帯の決まり、件数の閾値、戻し方の書き方を基準書にします。申請票の戻し方の欄に「時点・対象の行・手順」の3項目を設けます。
4週目:構文解析と件数をつなぐ
スクリプトで構文解析と検証環境での件数の取得を作り、Claude API の判定と一緒に一覧へ出すところまで作ります。この時点ではチケットにコメントせず、一覧だけを見ます。
2か月目: チケットのステータスを起点に動かし、verdict と質問をコメントします。needs_fix と needs_dba の件数を毎週数えます。3か月目以降: 本番で実行した後の件数と検証環境の件数を照合する仕組みを足し、1件20分が何分になったかを実測します。詳しい2名が needs_dba だけを読み、残りをほかの担当で回せた時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
UPDATE が条件を満たすすべての行を変更し、条件が true の行だけが更新されること。成功時に UPDATE count を返し、0件でもエラーとされないこと。RETURNING で更新前(OLD)と更新後(NEW)の値を返せること。FROM を使う更新で対象の1行が複数の行と結び付くと、どの行で更新されるかが容易に予測できず、副問い合わせのほうが安全とされること | PostgreSQL Documentation: UPDATE | 2026-10-07 |
--safe-updates を使うと、WHERE にキーの条件も LIMIT も無い UPDATE と DELETE が拒否されること。接続時に sql_safe_updates=1 などが設定されること | MySQL 8.4 Reference Manual: mysql Client Tips | 2026-10-07 |
構造化出力が output_config.format の type: "json_schema" で指定できること。enum が使え、数値の minimum・maximum などの制約には対応していないこと | Claude API Docs: Structured outputs | 2026-10-07 |
実行してよいかの判断と承認は、情報システム部の担当者が行ってください。 本記事は PostgreSQL・MySQL・Anthropic の公開文書で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0744)についてのご相談はこちらから。
