※この記事は「エムティーアイ Blog Summer 2026」の 6/2(火) 分の記事です。
スマートコンテンツ事業部で保守・開発を行っている 兒玉 です。
今回は、日々の運用業務で発生する SQL 作業を Claude Code の Skills 機能を使って半自動化してみた、という取り組みを紹介します。
はじめに(AI 活用について) 本記事の構成・初稿の作成には Claude Code を一部利用しています。最終的な文章・公開判断は執筆者が行っています。記事のテーマと相性が良いため、こうした取り組みの実例として活用方法も含めて紹介します。
はじめに
運用フェーズの業務には、「やる手順は決まっているけれど、毎回数十件単位の SQL を手で組み立てる」ようなルーチン作業がつきものです。私の担当しているシステムにも、決まったフォーマットの Excel を入力として、複数テーブルにまたがる数十件の INSERT 文を、複数環境(開発/検証/本番)それぞれに対して用意する、という作業が定期的に発生していました。
手順自体は社内 Wiki に書かれていて、それを見ながら手で SQL を組んでいくのですが、
- 表記揺れ(全角/半角、ハイフン有無、月数の表記など)が混ざりやすい
- 採番値や UUID の付与など「機械的に決まるが手で書くとミスにつながる」項目が多い
- 複数環境分用意するので、コピペ起因のミスがどうしても出る
- その結果、レビューの負荷も高い
といった構造的な辛さがありました。今回これを Claude Code の Skills 機能 を使って半自動化してみたので、設計上の工夫を中心に共有します。
Claude Code Skills について(簡単に)
Claude Code には「Skills」という仕組みがあり、Markdown と補助スクリプト(Python やシェル)をひとまとめにして、「特定の業務手順」を再利用可能な形で定義できます。プロジェクト固有の知識やワークフローを Claude Code に渡せるイメージです。
公式ドキュメントが充実しているので機能解説はそちらに譲りますが、ざっくり以下の構造です。
my-skill/ ├── SKILL.md # 手順・原則・テンプレート(Claude Code が読む) ├── scripts/ # 実行スクリプト(Python など) └── schemas/ # 設定ファイル(YAML など)
「Skill = Claude Code にやらせる業務手順の定義書 + 補助ツール群」と捉えるとイメージしやすいと思います。
題材にした作業
今回題材にしたのは、ざっくり以下のような作業です。実物のスキーマは伏せたいので、以降は 「架空の EC サイトで新しい出店者を登録する」 というシナリオに置き換えて説明します(テーブル名や ID 体系も全てこのフィクション用のものです)。
EC サイトに新しい出店者(merchant)と、その初期店舗(shop)を登録する。あらかじめ決まったフォーマットの Excel を入力として、対象環境の DB に、複数テーブルにまたがる数十件の INSERT を行う。外部キーの関係があるので順序も決まっている(merchant → shop → 周辺テーブル)。新規 ID は採番ルールに従って付与し、UUID は新規発番する。関連マスタの参照値(カテゴリコード等)は事前に SELECT で引いて埋める。これを複数環境にそれぞれ反映する。
ポイントは、この作業が 「ほぼ機械的に決まるが、最後の判断は人が行うべき」 という性質を持っていることです。新しい ID を何番にするか、店舗ページの公開 URL にどんなキーを使うか、といった部分は、機械が候補を出すのは構わないけれど、最終的には人が確認してから DB に流したい、という事情があったりします。
全体のワークフロー
先に全体像を示します。Excel と反映したい対象環境名(開発/検証/本番)を入力して、最終的に「動作確認済みの SQL ファイル」が手元に残る、というのがゴールです。途中、必ず人間の承認を挟むのがこの設計のキモです。

図1: 全体のワークフロー。人間の承認ステップ(黄色)を明示的に挟んでいる
設計のポイント
1. SQL の組み立ては Claude Codeの推論だけに任せない(Python テンプレートに分離)
実はこれ、最初は逆の作りをしていました。試作のいちばん最初の版では、「Claude Code に SQL クエリそのものを書かせる」 という方針で動かしていました。手元に SQL のテンプレート(先頭に BEGIN TRANSACTION、末尾に ROLLBACK TRANSACTION を置いた包み構造)を渡して、「この形で値を埋めて SQL を組み立て、ローカル DB に流して動作確認してきて」と頼んでいた、という流れです。
ところが試作を構築していたある時、Claude Code が テンプレートの中から INSERT 部分だけを抜き出して個別に実行する という挙動をしました。本来は BEGIN...ROLLBACK で包まれていて、丸ごと実行すれば中身が打ち消されるはずだったのですが、トランザクション制御の行が脱げた状態で、単独の INSERT が走った、という形です。結果としてローカル DB に書き込みが反映されました(手元の開発用 DB のみが対象で、検証環境・本番環境とは完全に分離された状態での出来事です)。
ローカルでの試作中の出来事だったので実害はゼロですし、むしろこの段階で挙動を見られたのは助かりました。ただ、その瞬間は素直にヒヤッとしました。「テンプレートとして渡したものを、解釈の都合で部分的に切り出されて実行される」というのは事前に想像できていなかったからです。
ここから設計を組み替えました。今のスキルでは Claude Code で SQL 文字列は組ませません。役割をはっきり分けています:
- SQL の骨格は、決定論的な Python テンプレートとして 固定で書いてある(コード変更を伴わない限り SQL の形は変わらない)
- Excel から取り出した値は、スキーマ定義(YAML)に従って構造化された JSON にする
- Python がその JSON を読んでテンプレートの値を埋め、
.sqlファイルを書き出す - Claude Code は「どの値を埋めるか(採番候補・UUID 等)の決定」と「ユーザーとの確認のやりとり」だけを担当する
つまり今の構成では、Claude Code は SQL 構文に一切触れません。SQL を文字列として組んでいるのは Python の決定論的な処理で、Claude Code はその外側で「素材の準備」と「人間との対話」を回す役割に限定しています。
その上で、二段目のガードとして、Python 側でも書き換え系 SQL(INSERT/UPDATE/DELETE/CREATE/ALTER/DROP/TRUNCATE/EXEC 等)をキーワード検知で拒否する処理を入れています。
具体的には、DB に SQL を投げる関数の入口で SQL 文字列を正規表現でスキャンし、これらのキーワードが含まれていればその場で例外を投げて、DB への接続そのものに到達させない、という仕組みです。
「Claude Code が SQL を書かない」という前提が万が一崩れたとしても書き換え系 SQL は実行されない、という最後の保険です。
なお、最終的に出てきた .sql ファイルは、SSMS や Azure Data Studio でユーザーが目視確認してから DB に流します。実行そのものは機械任せにしない、という運用です。

図2: アーキテクチャによる分離(第1層)+コードガード(第2層)の二段構え
2. 生成 SQL は BEGIN..ROLLBACK で包む
SQL の出力は必ず以下の形にしています。
SET XACT_ABORT ON; BEGIN TRANSACTION; -- 実行前 重複チェック SELECT -- INSERT 群(FK 順) -- 実行後 確認 SELECT ROLLBACK TRANSACTION; -- COMMIT TRANSACTION;
運用者はまずそのまま実行して、中間 SELECT の結果と最終的な行数を確認します。問題なければ末尾の ROLLBACK をコメントアウトして COMMIT に切り替え、もう一度実行する。これだけで「うっかり本番に書き込んでしまった」というクラスのミスはほぼ消えます。
3. 採番値・UUID は必ず人に承認させる
Skill のワークフローのなかに、明示的な「人間の承認ステップ」を組み込んでいます。Claude Code が DB を SELECT して採番候補を取得した後、たとえば以下のような形でユーザーに提示します(架空 EC サイトの新規出店者登録を例にした、説明用のサンプルです)。

図3: 採番候補の提示画面イメージ(架空 EC サイトの例)。各 ID に「何を表すか」を 1 行ずつ添える
各 ID について「何を意味しているか」を毎回 1〜2 行で添える、という小さい工夫を入れています。業務知識のない人がレビューに入っても判断できるようにする狙いです。承認(OK)が返ってこなければ次の SQL 生成ステップには進まない、という制御も合わせて入れています。
4. Excel フォーマットの差分は YAML スキーマで吸収する
運用が長くなると、入力 Excel のフォーマット自体も改訂されます(シートが増えたり、項目名が変わったり)。これを Python の中で if version == "1.1.0": と分岐を増やしていくと保守がすぐ苦しくなるので、最初から 「Excel のセル位置 → DB のカラム」のマッピングを YAML で持つ 構造にしました。
mapping: merchants.name: sheet: "基本情報" locator: type: "label_right" # ラベルの右隣セル label_col: "B" label_value: "出店者名" value_offset: 1 transform: null # 必要なら "no_hyphen" "trim" 等 required: true
新しいフォーマット v3.0.0 が来たら、schemas/v3.0.0.yaml を 1 枚追加するだけで対応できる。Python 側のコードは原則触らない、というルールにしています。

図4: Excel フォーマットの差分は YAML スキーマで吸収。新バージョン対応は YAML 1 枚追加で完結する
5. 欠損があったら絶対に進ませない
Excel に空欄があると、つい「とりあえずデフォルト値で進めようかな」と判断したくなりますが、ここはきっぱり止めるようにしました。必須項目に欠損があったら、その項目を全部ユーザーに見せて、依頼者に確認するなり、運用側で決めるなりしてから値を埋める、という流れです。
SKILL.md(プロンプト側の指示)と Python 側、両方に同じガードを入れていて、Claude Code が忘れても Python が止める、という二重チェックにしています。
運用してみての効果
| 観点 | Before | After |
|---|---|---|
| 作業時間(1 件あたり) | 数時間 | 30 分前後(レビュー含む) |
| 表記揺れ | 担当者ごとにばらつき | YAML の transform で吸収 |
| レビュー観点 | SQL 全文を目で追う | 採番値・UUID と SELECT 結果に集中 |
| 新メンバーへの引き継ぎ | Wiki + 口頭 | Skill が手順そのものを定義 |
なかでも効いたのは、「手順がコードと Markdown で表現されている」 ことでした。Wiki に書いた手順書は、書いた瞬間から実態とずれていきますが、Skill は実行するたびに最新の定義で動くので、ドキュメントの陳腐化が起きにくい。新しく入った人にも「これを読んで動かしてみて」で済みます。
詰まったポイント・学び
「親切すぎる Claude Code」をどう抑えるか
Claude Code は素直に協力的なので、放っておくと「ユーザーの確認を待たずに次のステップに進む」「空欄があっても、それっぽいデフォルトで進める」という挙動をしがちです。これは便利な一方で、運用作業では事故の温床になります。
対策として、SKILL.md の冒頭に 「厳守する原則」 のセクションを作って、各ルールに「なぜそうしたいか」と「代わりに何をするか」を必ずセットで書くようにしました。さらに、自然言語のルールだけだと気を利かせて一線を踏み越えてくることがあるので、コード側にも同じ趣旨のガードを入れています。プロンプトとコード、両方で守る のがコツだと思います。
「何を表すか」を必ず添えると、レビューが格段に楽になる
採番値の提示時に、各カラムについて「これは何を意味するか」を 1〜2 行で必ず説明させるようにしたら、レビューの負担が目に見えて減りました。業務知識がうろ覚えの状態でも、その場で意味を確認できるので認知負荷が下がりますし、知識のある人にレビューを依頼する場合も「自分が見るべきポイント」がはっきりします。
SKILL.md は「手順書 + プロンプト」のハイブリッドとして書く
当初、SKILL.md を普通の手順書として書いていたのですが、Claude Code に対する指示文として書き直したら一気に挙動が安定しました。意識した点は以下です。
- 「〜しないでください」とだけ書くのではなく、「こうしてほしい / なぜそうしたいか / 代わりに何をするか」 をセットで書く。理由まで書いてあると、ルールにきっちり当てはまらないグレーケースでも趣旨から外れにくい。
- 過去に事故った箇所は、理由まで書き残す。例えば「PARSEONLY での構文確認は使わない(過去にこれで誤って実 INSERT が走った事故あり)」のように、なぜそのルールがあるかを残しておくと、後から読んだ人や別の状況でも趣旨から外れにくい。
- 例外を許す曖昧な表現(「適宜判断して」「必要に応じて」など)は避ける。判断の余地を残すと、その隙を埋める形で振る舞いがブレる。
- 出力フォーマットは文章で説明するより、Markdown のコードブロックで具体例まで書く 方が安定する。
用語メモ
本文中に出てくる用語のうち、混同しやすい 2 つだけ補足しておきます。
| 用語 | 説明 |
|---|---|
| 書き換え系 SQL(DML) | INSERT / UPDATE / DELETE など、データを書き換える種類の SQL。本記事ではこの種類の SQL を Skill から実行させないことが核になる原則。 |
| 構造変更系 SQL(DDL) | CREATE / ALTER / DROP など、テーブルやカラムの構造を変える SQL。これも Skill 経由では実行しない。 |
おわりに
「機械的に決まるんだから自動化すればいい」と言うのは簡単ですが、実際にやってみて難しかったのは 「どこまで Claude Code にやらせて、どこから人がやるか」の線引き でした。最終的に、SQL の組み立てそのものは Python のテンプレートに任せ、Claude Code は値の決定とユーザーとのやりとりに役割を絞る、という形に落ち着いています。試作の最初に Claude Code に SQL を全部書かせて INSERT が走ったところから、ここに辿り着くまでが Skill 開発のほぼ全行程だった気がします。
同じような「手順は決まっているけど手作業だと辛い」運用作業を抱えている方の、なにかの足がかりになれば嬉しいです。