6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「表領域どれくらい空いてる?」を日本語で聞く。Oracle の DB 管理チャットを作ってみた

6
Posted at

初めに

データベースの面倒を見ていると、毎日のように小さな「調べもの」が発生します。

今のバージョンは? 表領域はあとどれくらい空いている? いま何で待たされている?

どれも SQL を書けば分かります。ただ、DBA_TABLESPACE_USAGE_METRICS の列名や、V$SYSTEM_EVENT の時間の単位を毎回正確に覚えているかというと、正直あやしいです。

そこで、自然言語で質問すると Oracle の SQL を作ってくれる「DB 管理チャット」という画面を作りました。Production Ready NL2SQL の「データ準備」の中にある、DBA 向けの機能です。

ただし、DB 管理で AI に SQL を作らせるのは、業務データの検索よりずっと怖いです。DROP や TRUNCATE を AI が勝手に実行したら、取り返しがつきません。

なので、この画面は次の考え方で作っています。

  • AI は SQL を作るだけ。実行するかどうかは人が決める
  • 生成した SQL は 必ず画面に見せる
  • 失敗したら、AI がエラーを分析して直した SQL を示す(でも、使うかどうかは人が決める)

この記事では、DB 管理チャットの機能と操作を、実際の画面と 3 つの質問で紹介します。

先に結論

DB 管理チャットでできることを先にまとめます。

やりたいこと DB 管理チャットでの動き
管理の質問を自然言語で聞く データ辞書・動的性能ビュー(V$ / DBA_)を使う SQL を生成する
複数のことを一度に聞く 1 つの質問から 複数の文を作り、文ごとに実行するか「すべて実行」で上から順に実行する
結果を全部確かめる 会話の中は先頭だけのプレビュー。「すべての行を見る」で右のパネルにページ付きで全行を出し、CSV でも落とせる
失敗を直す 「AI でエラーを分析」で原因と修正した SQL を示し、「修正した SQL を使う」で差し替えて再実行する
変更系の SQL を安全に扱う SELECT 以外は 実行確認語(ADMIN_EXECUTE)を入れないと実行できない
後から見直す 会話は利用者ごとに保存され、左の「会話の履歴」から開き直せる

流れを図にすると、こうなります。

ポイントは、どこにも「AI が自動で実行する」矢印がないことです。

DB 管理チャットの位置づけ

Production Ready NL2SQL には、SQL を扱う画面がいくつかあります。DB 管理チャットは、その間を埋める画面です。

画面 対象 SQL の書き手 実行できる文
チャット 業務プロファイルの範囲の業務データ AI SELECT だけ
管理 SQL を実行 DB 全体 人(手で書く) すべて
DB 管理チャット DB 全体 AI(人が確かめて実行) すべて(変更系は確認語つき)

DBA の役割の利用者向けの機能なので、メニューの権限は既定で system_admin にしか付いていません。外部の MCP クライアントや API キーからは呼べない、画面だけの機能にしています。

画面を開くとこうなります。

01_screen.png

空の状態の案内に、使い方がまとまっています。

  • 同じ会話の中では、前の質問と SQL を踏まえて次の SQL を作る(例:「表領域の使用状況」の後に「使用率の高い順にして」)
  • 生成した SQL は自動では実行しない
  • SELECT は「実行」、データや構造を変える文は実行確認語を入れて実行する
  • 複数の文は「すべて実行」で上から順に実行できる

ここからは、実際に 3 つの質問を投げてみます。

検証環境は Oracle Autonomous AI Database です。SQL の生成とエラー分析には、OCI Enterprise AI のテキストモデル(今回は xai.grok-4.3)を使っています。LLM の出力は毎回少しずつ変わるので、同じ質問でも SQL が少し違うことがあります。

質問 1:バージョンと表領域の使用率(複数の文と「すべて実行」)

最初の質問です。

データベースのバージョンと、表領域ごとの使用率を確認したい

送信すると、数秒で SQL が返ってきます。

02_q1_generated.png

「バージョン」と「表領域の使用率」は別のことなので、2 つの SELECT 文に分かれています。

-- 文 1
SELECT BANNER_FULL FROM V$VERSION

-- 文 2
SELECT u.TABLESPACE_NAME,
       u.USED_SPACE * t.BLOCK_SIZE / 1024 / 1024 AS USED_MB,
       u.TABLESPACE_SIZE * t.BLOCK_SIZE / 1024 / 1024 AS TOTAL_MB,
       u.USED_PERCENT
  FROM DBA_TABLESPACE_USAGE_METRICS u
  JOIN DBA_TABLESPACES t ON u.TABLESPACE_NAME = t.TABLESPACE_NAME

DBA_TABLESPACE_USAGE_METRICS の USED_SPACE はブロック数なので、DBA_TABLESPACES の BLOCK_SIZE を掛けて MB にしています。ここを覚えていなくても SQL が出てくるのは、地味にありがたいところです。

画面で見てほしいのは、文ごとに付いているバッジです。

  • 文 1 / 文 2:文の番号
  • 読み取り専用:サーバーが分類した結果(SELECT なので確認語は不要)
  • SELECT:文の種類

この分類は AI の判断ではなく、サーバーがコードで行います。AI が「これは安全です」と言っても、それを信じない作りです。

UNION で 1 つにまとめず、読むことごとに文を分けているのも意図的です。結果を文ごとに並べて読めるからです。

文ごとに「実行」してもよいのですが、ここでは右上の「すべて実行」を押します。

03_q1_run_all.png

「すべて成功・2 文すべてが成功しました。」の要約がまとめて出て、それぞれの文の直下に結果が並びます。

04_q1_results.png

「すべて実行」は、SQL Developer のワークシートの「スクリプトの実行」に近い動きです。

  • 上から順に実行し、最初のエラーで止める
  • 1 つのトランザクションで実行し、全部成功したときだけ commit する
  • どの文が成功し、どの文を実行しなかったかを文ごとに示す

質問 2:待機イベントの上位 100 件(結果の全データのパネル)

2 つ目は、行数の多い結果を見る質問です。

累計の待機時間が長い待機イベントを上位100件、待機クラスと平均待機時間(ミリ秒)つきで見せて。アイドルの待機は除いて

生成された SQL です。

SELECT EVENT, WAIT_CLASS, TOTAL_WAITS,
       TIME_WAITED * 10  AS CUMULATIVE_WAIT_MS,
       AVERAGE_WAIT * 10 AS AVG_WAIT_MS
  FROM V$SYSTEM_EVENT
 WHERE WAIT_CLASS <> 'Idle'
 ORDER BY TIME_WAITED DESC
 FETCH FIRST 100 ROWS ONLY

V$SYSTEM_EVENT の TIME_WAITED と AVERAGE_WAIT は 1/100 秒単位なので、ミリ秒にするために 10 を掛けています。「ミリ秒で」と言っただけで単位の変換まで入るのは便利です。

実行すると、結果は 100 行です。

06_q2_result.png

会話の中はプレビューです。会話の流れを崩さないように、表は一定の高さで内側をスクロールし、先頭の 50 行までを描きます(「ここでは先頭の 50 行を表示しています。取得した 100 行は『すべての行を見る』で確認できます。」)。

全部の行を確かめたいときは「すべての行を見る」を押します。

07_q2_all_rows_sheet.png

右側に「実行結果(100 行)」のパネルが開きます。

  • 1 ページの行数を 25 / 50 / 100 行から選べる
  • ページ送りで全行をたどれる
  • 右上の「CSV をダウンロード」で、取得した行をそのまま Excel などに持っていける

会話は左に残ったままなので、結果を見ながら次の質問を考えられるのがこの形の良いところです。

質問 3:LISTAGG が 4000 バイトを超える(AI でエラーを分析)

3 つ目は、わざと失敗しやすい質問にしました。

Oracle が管理するスキーマ(ORACLE_MAINTAINED = 'Y')ごとに、表の数と、すべての表名をカンマ区切りで 1 行にまとめて見せて

生成された SQL は、素直に LISTAGG を使っています。

SELECT OWNER, COUNT(*) AS TABLE_COUNT,
       LISTAGG(TABLE_NAME, ',') WITHIN GROUP (ORDER BY TABLE_NAME) AS TABLE_NAMES
  FROM DBA_TABLES
 WHERE OWNER IN (SELECT USERNAME FROM DBA_USERS WHERE ORACLE_MAINTAINED = 'Y')
 GROUP BY OWNER
 ORDER BY OWNER

文法としては正しいのですが、SYS や APEX_… のように表が数百〜数千あるスキーマでは、連結した文字列が VARCHAR2 の上限を超えます。実行すると、案の定エラーになりました。

08_q3_error.png

ORA-01489: result of string concatenation is too long

ここで「AI でエラーを分析」を押します。

09_q3_ai_analysis.png

AI の分析は、こう返ってきました。

  • エラーの原因:LISTAGG で全テーブル名を連結した結果が VARCHAR2 の上限(4000 バイト)を超えた
  • 直し方:XMLAGG + XMLELEMENT で CLOB を作る形に変更する
  • 結論:元の集計処理を保ったまま、長い文字列に対応した SQL に修正する

修正した SQL はこちらです。

SELECT OWNER, COUNT(*) AS TABLE_COUNT,
       RTRIM(XMLAGG(XMLELEMENT(e, TABLE_NAME || ',') ORDER BY TABLE_NAME)
             .EXTRACT('//text()').GETCLOBVAL(), ',') AS TABLE_NAMES
  FROM DBA_TABLES
 WHERE OWNER IN (SELECT USERNAME FROM DBA_USERS WHERE ORACLE_MAINTAINED = 'Y')
 GROUP BY OWNER
 ORDER BY OWNER

XMLAGG で CLOB にする、昔からある定番の回避策です。

ここでも AI は勝手に実行しません。修正した SQL の区画にも 読み取り専用 / SELECT のバッジが付いていて、「修正した SQL を使う」を押して初めて、元の文と差し替わります。

差し替えた SQL はサーバーが分類し直し、確認からやり直します。SELECT だった文を AI が変更系の文に書き換えても、確認語なしで実行されることはありません。

差し替えて「実行」すると、今度は成功しました。

10_q3_fixed_result.png

文の上に「AI のエラー分析で修正した SQL です。」と表示されるので、後から見ても、どれが AI に直してもらった SQL なのかが分かります。

分析には、エラーの内容だけでなく、SQL が参照しているオブジェクトの実際の列も渡しています。データ辞書のビューは、AI が記憶で列名を書いて ORA-00904(列が無い)になりやすいので、実在する列だけで直した SQL を作らせるためです。

変更系の SQL:実行確認語と「すべて実行」のトランザクション

ここまでの 3 つの質問はすべて SELECT でした。データや構造を変える SQL も、同じ画面で扱えます。

検証用の表 DEMO_WORK(ID 数値の主キー、NOTE 文字列 100)を作って、3 行入れてから、件数を確認して

この質問では、CREATE TABLE → INSERT × 3 → SELECT COUNT(*) の 5 文が生成されました(※ この記事のためには実行していません)。

11_change_confirm.png

変更系の文には、次のガードが付きます。

  • バッジが 変更あり になり、「この文はデータベースを変更します」の警告が出る
  • 実行確認語 ADMIN_EXECUTE を入力するまで「実行」を押せない(1 つの対象を消す DROP / TRUNCATE は、確認語が対象の名前になる)
  • DDL には「Oracle が暗黙に commit するため、実行すると元に戻せません」の警告が付く
  • 「すべて実行」の区画には、トランザクションの扱い(最初のエラーで止め、全部成功したときだけ commit、失敗したら DML を rollback)の説明が出る
  • 確認語は 1 回ごと。実行したら消え、SQL が変わると最初からやり直し

確認語を毎回打つのは少し面倒ですが、DB 管理の画面ではこの「面倒さ」が大事だと考えています。

なお、方針として止める操作もあります。製品自身の表(NL2SQL_ などで始まる表)や動的 SQL は、AI が SQL を作ってもサーバーが「実行できない」にします。実際に「(製品の表)を TRUNCATE して」と頼むと、AI は TRUNCATE を作らず、表の存在を確認する SELECT を返しました(下の画面の右側)。

会話の履歴

DB 管理チャットの会話は、利用者ごとに保存されます。左上のボタンで「会話の履歴」を開くと、過去の会話を開き直せます。

12_history.png

開き直した会話では、結果の行そのものは保存していないので、文ごとに「前回の実行(…): N 行・M 列」の要約と「もう一度実行」が出ます。

  • 結果の行を残さないのは、DB の中身(場合によっては機密のデータ)を会話の保存先に複製しないため
  • 実行した SQL・確認語の有無・結果・commit / rollback は、会話とは別に監査の表に、実行した文ごとに残る(会話を消しても監査の記録は消えない)

使ってみて分かったこと

検証中に気づいた点も、正直に書いておきます。

  • AI のエラー分析は、1 回で直るとは限らない
    V$PARAMETER の VALUE を TO_NUMBER で比べる質問では、ORA-01722(数値に変換できない)が出ました。「分析 → 修正 → 実行」を繰り返すと、AI が「サブクエリで先に絞る」「WITH 句にする」「TYPE で絞る」と方針を変えましたが、Oracle の述語の評価順の問題は解けず、最後は最初と同じ SQL に戻りました。今の分析は「今の SQL と今のエラー」だけを見ていて、前に試して失敗した方針を覚えていないためです。前の修正の履歴を分析に渡す改善を進めています。
  • 生成した SQL を読むのは、人の仕事
    修正した SQL が正しく見えても、意味が変わっていないかは人が確かめる必要があります。DB 管理チャットが「実行」を必ず人に押させるのは、そのためです。

AI は「SQL を思い出す手間」と「エラーの原因を調べる手間」を減らしてくれます。でも、「実行してよいかを決める」のは人に残しておく。DB 管理では、この分担がちょうどよいと感じました。

まとめ

DB 管理チャットは、DBA の「ちょっとした調べもの」を自然言語で済ませるための画面です。

  • 質問から、データ辞書・動的性能ビューを使う Oracle の SQL を生成する
  • 1 つの質問から複数の文を作り、文ごとの「実行」か「すべて実行」で動かす
  • 会話の中はプレビュー、「すべての行を見る」で右のパネルに全行を出し、CSV でも持ち出せる
  • 失敗したら「AI でエラーを分析」で原因と修正した SQL を示し、「修正した SQL を使う」で差し替える
  • 文の分類と確認はサーバーが行い、変更系は実行確認語がないと実行できない
  • 会話は履歴に残り、実行は監査の表に残る

AI に SQL を書かせる。
でも、実行するかどうかは人が決める。
DB 管理の画面では、この線を引いておくことが一番大事だと思います。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?