【完全版】Oracle Databaseでテーブル一覧を取得する全方法

【完全版】Oracle Databaseでテーブル一覧を取得する全方法

「Oracleでテーブル一覧を取得したい」――この一見シンプルな要件は、状況によって最適なSQLが大きく変わる奥深いテーマです。

  • 自分が作ったテーブルだけ見たい
  • 他ユーザーのスキーマも含めて全テーブルを見たい
  • テーブルサイズや件数も合わせて確認したい
  • マルチテナント環境(CDB/PDB)の全テーブルを横断的に確認したい

これらは全部「テーブル一覧」ですが、それぞれ異なるSQLが必要です。本記事では、Oracle Databaseでテーブル一覧を取得するすべての方法を、実務でそのまま使えるSQL集として整理しました。USER_TABLES・ALL_TABLES・DBA_TABLESの違いから、テーブルサイズ込み一覧、コメント・制約・インデックスとの結合、SQL Developer/A5:SQL Mk-2でのGUI操作、CSV出力まで、この1本で完結します。


目次

結論:とにかく今すぐ知りたい人向けの3パターン

時間がない方向けに、最頻出の3パターンを先に示します。

①自分のテーブルだけ見たい

SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME;

②全スキーマのテーブルを横断的に見たい(DBA権限あり)

SELECT OWNER, TABLE_NAME 
FROM DBA_TABLES 
WHERE OWNER NOT IN ('SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'APPQOSSYS', 'XDB', 'CTXSYS', 'MDSYS', 'ORDDATA', 'WMSYS', 'GSMADMIN_INTERNAL', 'SYSTEM') 
ORDER BY OWNER, TABLE_NAME;

③特定のスキーマのテーブルだけ見たい

SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'HR' ORDER BY TABLE_NAME;

詳しい使い分けと応用クエリは以下で順に解説します。


まず押さえるべき:USER_TABLES / ALL_TABLES / DBA_TABLES の違い

Oracleには、テーブル一覧を取得するためのデータディクショナリビューが3種類あり、取得できる範囲と必要な権限が異なります

ビュー名取得範囲必要権限OWNER列
USER_TABLES自分が所有するテーブルのみ不要(誰でも使用可)なし(自分のみ)
ALL_TABLES自分がアクセス可能なテーブル(自分のもの+権限を付与されたもの)不要あり
DBA_TABLESデータベース内の全テーブルDBA権限または SELECT ANY DICTIONARY 権限あり

使い分けの指針

  • 開発者が自分のスキーマで作業中USER_TABLES
  • 複数スキーマを参照する業務アプリ開発ALL_TABLES
  • DBA・運用担当が全体管理DBA_TABLES

マルチテナント環境(CDB)の場合

12c以降のCDB環境では、さらに CDB_TABLES も使えます。

ビュー名取得範囲
CDB_TABLESCDB全体(全PDB)の全テーブル ※ルートから接続時のみ完全な結果

CDB_TABLESには CON_ID 列が追加され、どのPDBに属するテーブルかが分かります。


基本パターン:シンプルなテーブル一覧取得

自分のテーブル一覧

SELECT TABLE_NAME 
FROM USER_TABLES 
ORDER BY TABLE_NAME;

アクセス可能な全テーブル一覧

SELECT OWNER, TABLE_NAME 
FROM ALL_TABLES 
ORDER BY OWNER, TABLE_NAME;

DB全体の全テーブル一覧(DBA権限必要)

SELECT OWNER, TABLE_NAME 
FROM DBA_TABLES 
ORDER BY OWNER, TABLE_NAME;

CDB全体の全テーブル一覧(マルチテナント)

SELECT CON_ID, OWNER, TABLE_NAME 
FROM CDB_TABLES 
WHERE OWNER NOT IN ('SYS', 'SYSTEM') 
ORDER BY CON_ID, OWNER, TABLE_NAME;

テーブル名で絞り込む(完全一致・部分一致)

完全一致

SELECT * 
FROM USER_TABLES 
WHERE TABLE_NAME = 'EMPLOYEES';


⚠️ 大文字小文字の注意: Oracleのテーブル名は内部的に大文字で格納されています。クォートなしで 

CREATE TABLE employees と作成したテーブルも、データディクショナリ上は EMPLOYEES です。検索時も大文字で指定してください。

前方一致

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TABLE_NAME LIKE 'EMP%' 
ORDER BY TABLE_NAME;

後方一致

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TABLE_NAME LIKE '%_LOG' 
ORDER BY TABLE_NAME;

_(アンダースコア)は1文字のワイルドカードなので、リテラルとして扱いたい場合はエスケープが必要です:

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TABLE_NAME LIKE '%\_LOG' ESCAPE '\';

部分一致(大小文字を無視)

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE UPPER(TABLE_NAME) LIKE '%LOG%' 
ORDER BY TABLE_NAME;

正規表現で検索

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE REGEXP_LIKE(TABLE_NAME, '^(EMP|DEPT)_.+$') 
ORDER BY TABLE_NAME;

システムテーブルを除外する

DBA_TABLESを使うと、Oracle内部のシステムテーブルが大量に表示されてしまいます。ユーザー作成テーブルだけを抽出するには、以下のように除外します。

主要システムスキーマを除外

SELECT OWNER, TABLE_NAME 
FROM DBA_TABLES 
WHERE OWNER NOT IN (
    'SYS', 'SYSTEM', 'OUTLN', 'DBSNMP', 'APPQOSSYS', 
    'XDB', 'CTXSYS', 'MDSYS', 'ORDDATA', 'WMSYS', 
    'GSMADMIN_INTERNAL', 'OJVMSYS', 'LBACSYS', 
    'AUDSYS', 'DVSYS', 'OLAPSYS', 'ORACLE_OCM',
    'ANONYMOUS', 'APEX_PUBLIC_USER', 'FLOWS_FILES',
    'REMOTE_SCHEDULER_AGENT'
) 
ORDER BY OWNER, TABLE_NAME;

Oracle推奨:ORACLE_MAINTAINEDを使う(12c以降)

12c以降では、Oracle管理のスキーマを示すフラグ ORACLE_MAINTAINED が追加されました。これを使う方が新スキーマの追加に対しても安全です。

SELECT t.OWNER, t.TABLE_NAME 
FROM DBA_TABLES t 
JOIN DBA_USERS u ON t.OWNER = u.USERNAME 
WHERE u.ORACLE_MAINTAINED = 'N' 
ORDER BY t.OWNER, t.TABLE_NAME;

テーブル数を集計する

自分のテーブル数

SELECT COUNT(*) AS TABLE_COUNT FROM USER_TABLES;

スキーマ別のテーブル数(ランキング)

SELECT OWNER, COUNT(*) AS TABLE_COUNT 
FROM DBA_TABLES 
WHERE OWNER NOT IN ('SYS', 'SYSTEM') 
GROUP BY OWNER 
ORDER BY TABLE_COUNT DESC;

テーブル名の頭文字別カウント

SELECT SUBSTR(TABLE_NAME, 1, 1) AS INITIAL, COUNT(*) 
FROM USER_TABLES 
GROUP BY SUBSTR(TABLE_NAME, 1, 1) 
ORDER BY INITIAL;

【実践】テーブルサイズ込みで一覧取得する

実務でもっとも需要が高い「テーブルサイズ」を含めた一覧取得です。容量計画やパフォーマンスチューニングで必須となります。

自分のテーブルのサイズ一覧

SELECT 
    s.SEGMENT_NAME AS TABLE_NAME,
    ROUND(s.BYTES / 1024 / 1024, 2) AS SIZE_MB,
    s.BLOCKS,
    s.EXTENTS,
    s.TABLESPACE_NAME
FROM USER_SEGMENTS s
WHERE s.SEGMENT_TYPE = 'TABLE'
ORDER BY s.BYTES DESC;

全テーブルのサイズ一覧(DBA権限必要)

SELECT 
    s.OWNER,
    s.SEGMENT_NAME AS TABLE_NAME,
    ROUND(s.BYTES / 1024 / 1024, 2) AS SIZE_MB,
    s.TABLESPACE_NAME
FROM DBA_SEGMENTS s
WHERE s.SEGMENT_TYPE = 'TABLE'
  AND s.OWNER NOT IN ('SYS', 'SYSTEM')
ORDER BY s.BYTES DESC;

サイズTop10のテーブル

SELECT * 
FROM (
    SELECT 
        OWNER,
        SEGMENT_NAME AS TABLE_NAME,
        ROUND(BYTES / 1024 / 1024, 2) AS SIZE_MB
    FROM DBA_SEGMENTS
    WHERE SEGMENT_TYPE = 'TABLE'
      AND OWNER NOT IN ('SYS', 'SYSTEM')
    ORDER BY BYTES DESC
)
WHERE ROWNUM <= 10;

12c以降は FETCH FIRST 構文が使えます:

SELECT 
    OWNER,
    SEGMENT_NAME AS TABLE_NAME,
    ROUND(BYTES / 1024 / 1024, 2) AS SIZE_MB
FROM DBA_SEGMENTS
WHERE SEGMENT_TYPE = 'TABLE'
  AND OWNER NOT IN ('SYS', 'SYSTEM')
ORDER BY BYTES DESC
FETCH FIRST 10 ROWS ONLY;

テーブルの行数(件数)込みで一覧取得する

統計情報の概算行数(高速)

DBMS_STATSで収集された統計情報から行数を取得する方法です。高速だが、最新の統計情報が必要です。

SELECT 
    TABLE_NAME,
    NUM_ROWS,
    LAST_ANALYZED
FROM USER_TABLES
ORDER BY NUM_ROWS DESC NULLS LAST;

統計情報を最新化するには:

EXEC DBMS_STATS.GATHER_SCHEMA_STATS(USER);

正確な行数を取得(低速)

実際の件数を取得するには COUNT(*) を各テーブルに対して実行する必要があります。動的SQLで一括取得:

SET SERVEROUTPUT ON
DECLARE
    v_count NUMBER;
BEGIN
    FOR rec IN (SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME) LOOP
        EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM "' || rec.TABLE_NAME || '"' INTO v_count;
        DBMS_OUTPUT.PUT_LINE(RPAD(rec.TABLE_NAME, 30) || ': ' || v_count);
    END LOOP;
END;
/
⚠️ 大規模DB注意: 全テーブルに COUNT(*) を実行すると非常に時間がかかります。本番環境では統計情報ベースの NUM_ROWS の利用を推奨します。

テーブルコメント込みで一覧取得する

テーブルにコメントが設定されている場合、それも含めて取得できます。

自分のテーブル+コメント

SELECT 
    t.TABLE_NAME,
    c.COMMENTS
FROM USER_TABLES t
LEFT JOIN USER_TAB_COMMENTS c 
    ON t.TABLE_NAME = c.TABLE_NAME
ORDER BY t.TABLE_NAME;

全テーブル+コメント

SELECT 
    t.OWNER,
    t.TABLE_NAME,
    c.COMMENTS
FROM ALL_TABLES t
LEFT JOIN ALL_TAB_COMMENTS c 
    ON t.OWNER = c.OWNER 
    AND t.TABLE_NAME = c.TABLE_NAME
WHERE t.OWNER = 'HR'
ORDER BY t.TABLE_NAME;

カラム情報込みで一覧取得する

テーブルとカラム情報を結合した「テーブル定義書」のような形式で取得できます。

テーブル+カラム+データ型

SELECT 
    t.TABLE_NAME,
    c.COLUMN_ID,
    c.COLUMN_NAME,
    c.DATA_TYPE,
    c.DATA_LENGTH,
    c.NULLABLE,
    cc.COMMENTS
FROM USER_TABLES t
JOIN USER_TAB_COLUMNS c 
    ON t.TABLE_NAME = c.TABLE_NAME
LEFT JOIN USER_COL_COMMENTS cc 
    ON c.TABLE_NAME = cc.TABLE_NAME 
    AND c.COLUMN_NAME = cc.COLUMN_NAME
ORDER BY t.TABLE_NAME, c.COLUMN_ID;

特定テーブルのカラム一覧

SELECT 
    COLUMN_ID,
    COLUMN_NAME,
    DATA_TYPE,
    DATA_LENGTH,
    DATA_PRECISION,
    DATA_SCALE,
    NULLABLE,
    DATA_DEFAULT
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = 'EMPLOYEES'
ORDER BY COLUMN_ID;

主キー・外部キー込みで一覧取得する

主キーを持つテーブル一覧

SELECT 
    c.TABLE_NAME,
    c.CONSTRAINT_NAME,
    LISTAGG(cc.COLUMN_NAME, ', ') WITHIN GROUP (ORDER BY cc.POSITION) AS PK_COLUMNS
FROM USER_CONSTRAINTS c
JOIN USER_CONS_COLUMNS cc 
    ON c.CONSTRAINT_NAME = cc.CONSTRAINT_NAME
WHERE c.CONSTRAINT_TYPE = 'P'
GROUP BY c.TABLE_NAME, c.CONSTRAINT_NAME
ORDER BY c.TABLE_NAME;

主キーを持たないテーブル(要確認テーブル)

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TABLE_NAME NOT IN (
    SELECT TABLE_NAME 
    FROM USER_CONSTRAINTS 
    WHERE CONSTRAINT_TYPE = 'P'
)
ORDER BY TABLE_NAME;

外部キーの関連テーブル一覧

SELECT 
    c.TABLE_NAME AS CHILD_TABLE,
    c.CONSTRAINT_NAME AS FK_NAME,
    r.TABLE_NAME AS PARENT_TABLE,
    r.CONSTRAINT_NAME AS PK_NAME
FROM USER_CONSTRAINTS c
JOIN USER_CONSTRAINTS r 
    ON c.R_CONSTRAINT_NAME = r.CONSTRAINT_NAME
WHERE c.CONSTRAINT_TYPE = 'R'
ORDER BY c.TABLE_NAME;

インデックス情報込みで一覧取得する

テーブル+インデックス数

SELECT 
    t.TABLE_NAME,
    COUNT(i.INDEX_NAME) AS INDEX_COUNT
FROM USER_TABLES t
LEFT JOIN USER_INDEXES i 
    ON t.TABLE_NAME = i.TABLE_NAME
GROUP BY t.TABLE_NAME
ORDER BY t.TABLE_NAME;

インデックスがないテーブル

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TABLE_NAME NOT IN (SELECT TABLE_NAME FROM USER_INDEXES);

テーブル種別で絞り込む

通常テーブルのみ(一時テーブル等を除外)

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TEMPORARY = 'N' 
  AND IOT_TYPE IS NULL
ORDER BY TABLE_NAME;

一時テーブル(グローバル一時表)のみ

SELECT TABLE_NAME, DURATION 
FROM USER_TABLES 
WHERE TEMPORARY = 'Y' 
ORDER BY TABLE_NAME;

パーティション化されたテーブル

SELECT TABLE_NAME, PARTITIONING_TYPE 
FROM USER_PART_TABLES 
ORDER BY TABLE_NAME;

外部テーブル

SELECT TABLE_NAME, TYPE_NAME, DEFAULT_DIRECTORY_NAME 
FROM USER_EXTERNAL_TABLES 
ORDER BY TABLE_NAME;

IOT(索引構成表)

SELECT TABLE_NAME, IOT_TYPE 
FROM USER_TABLES 
WHERE IOT_TYPE IS NOT NULL;

最終更新日・アクセス日込みで一覧取得する

統計情報の最終収集日

SELECT 
    TABLE_NAME,
    NUM_ROWS,
    LAST_ANALYZED
FROM USER_TABLES
ORDER BY LAST_ANALYZED DESC NULLS LAST;

最終DML(更新)時刻(おおまかな目安)

SELECT 
    tm.TABLE_NAME,
    tm.INSERTS,
    tm.UPDATES,
    tm.DELETES,
    tm.TIMESTAMP AS LAST_DML_TIME
FROM USER_TAB_MODIFICATIONS tm
ORDER BY tm.TIMESTAMP DESC;
⚠️ USER_TAB_MODIFICATIONS の値は内部バッファのフラッシュ後に反映されます。即時反映には以下を実行:
EXEC DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

テーブル作成日

SELECT 
    OBJECT_NAME AS TABLE_NAME,
    CREATED,
    LAST_DDL_TIME
FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'TABLE'
ORDER BY CREATED DESC;

GUIツールでテーブル一覧を確認する

SQL Developer

最も標準的な方法です:

  1. 接続を展開
  2. テーブル(フィルタ済)」を展開
  3. テーブル一覧が表示される

フィルタ機能の活用: 「テーブル」を右クリック→「フィルタの適用」で、特定の条件のみ表示可能。例: 名前が「EMP%」で始まるテーブルだけ表示。

レポート機能: 「表示」→「レポート」→「データ・ディクショナリ・レポート」→「ユーザー定義」→「自分のユーザーが所有するすべてのオブジェクト」で、より詳細な情報が確認できます。

A5:SQL Mk-2

国産の人気SQLクライアント:

  1. ツリーから対象データベースを展開
  2. スキーマを展開→「」をクリック
  3. 右ペインにテーブル一覧が表示される

「表」を右クリック→「ER図にすべてのテーブルを追加」で、ER図形式で一覧できます。

Oracle SQL Developer Web(APEX付属)

ブラウザベースで動作するOracle純正ツール:

  1. SQL Workshop → Object Browser
  2. ドロップダウンから「Tables」を選択
  3. テーブル一覧が表示される

CSVファイルにテーブル一覧をエクスポートする

SQL*Plusを使った方法

SET MARKUP CSV ON
SET FEEDBACK OFF
SET HEADING ON
SPOOL table_list.csv

SELECT OWNER, TABLE_NAME, NUM_ROWS, LAST_ANALYZED 
FROM DBA_TABLES 
WHERE OWNER NOT IN ('SYS', 'SYSTEM') 
ORDER BY OWNER, TABLE_NAME;

SPOOL OFF

SQL Developerを使った方法

  1. クエリを実行
  2. 結果セットを右クリック→「エクスポート
  3. 形式に「CSV」を選択して保存

A5:SQL Mk-2を使った方法

クエリ結果ウィンドウで右クリック→「CSVに出力


プログラム言語からテーブル一覧を取得する

Python(python-oracledb)

import oracledb

conn = oracledb.connect(user="hr", password="hr", dsn="localhost:1521/XEPDB1")
cursor = conn.cursor()

cursor.execute("""
    SELECT TABLE_NAME 
    FROM USER_TABLES 
    ORDER BY TABLE_NAME
""")

for row in cursor:
    print(row[0])

cursor.close()
conn.close()

Java(JDBC)

String sql = "SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME";
try (PreparedStatement ps = conn.prepareStatement(sql);
     ResultSet rs = ps.executeQuery()) {
    while (rs.next()) {
        System.out.println(rs.getString("TABLE_NAME"));
    }
}

Node.js(node-oracledb)

const oracledb = require('oracledb');

async function listTables() {
    const conn = await oracledb.getConnection({
        user: "hr",
        password: "hr",
        connectString: "localhost:1521/XEPDB1"
    });
    const result = await conn.execute(
        "SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME"
    );
    result.rows.forEach(row => console.log(row[0]));
    await conn.close();
}

listTables();

【応用】テーブル定義(DDL)を含めて取得する

テーブル一覧+それぞれのCREATE TABLE文を取得する方法です。データベース移行や定義のバックアップに使えます。

SELECT 
    TABLE_NAME,
    DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) AS DDL
FROM USER_TABLES
ORDER BY TABLE_NAME;

ストレージ句・制約句などを除外して見やすくする場合:

BEGIN
    DBMS_METADATA.SET_TRANSFORM_PARAM(
        DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE);
    DBMS_METADATA.SET_TRANSFORM_PARAM(
        DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
END;
/

SELECT DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) FROM USER_TABLES;

ビューと一緒にオブジェクト一覧を取得する

「テーブル」だけでなく、ビュー・シノニムなども含めた一覧が必要な場合:

SELECT 
    OBJECT_TYPE,
    OBJECT_NAME,
    CREATED,
    STATUS
FROM USER_OBJECTS
WHERE OBJECT_TYPE IN ('TABLE', 'VIEW', 'MATERIALIZED VIEW', 'SYNONYM')
ORDER BY OBJECT_TYPE, OBJECT_NAME;

CDB/PDB環境での注意点

マルチテナント環境では、接続先によって取得結果が変わります。

現在の接続コンテナを確認

SHOW CON_NAME
-- または
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;

PDBに接続している場合

-- そのPDB内のテーブルのみ
SELECT * FROM DBA_TABLES;

ルートCDBに接続している場合

-- 全PDBのテーブル
SELECT CON_ID, OWNER, TABLE_NAME 
FROM CDB_TABLES 
WHERE OWNER NOT IN ('SYS', 'SYSTEM') 
ORDER BY CON_ID;

PDB一覧を確認

SELECT CON_ID, NAME, OPEN_MODE FROM V$PDBS;

用途別:使い分けクイックリファレンス

やりたいこと推奨SQL/方法
自分のテーブル名一覧SELECT TABLE_NAME FROM USER_TABLES
アクセス可能テーブル全部SELECT * FROM ALL_TABLES
DB全体のテーブルSELECT * FROM DBA_TABLES(要権限)
マルチテナント全体SELECT * FROM CDB_TABLES
テーブル数のカウントSELECT COUNT(*) FROM USER_TABLES
サイズ込みDBA_SEGMENTS JOIN
件数込みUSER_TABLES.NUM_ROWS
定義書として出力USER_TAB_COLUMNS JOIN
GUIで閲覧SQL Developer / A5:SQL Mk-2
CSVに出力SQL*Plus SET MARKUP CSV ON

よくある質問(FAQ)

Q1. USER_TABLESに表示されるのに、SELECTすると「ORA-00942: 表またはビューが存在しません」が出ます

USER_TABLESに表示されているなら、テーブル自体は存在します。可能性として:

  • テーブル名に小文字・記号が含まれている("My_Table" のように二重引用符で囲んで作成された場合)→ SELECT時も SELECT * FROM "My_Table" のように二重引用符必要
  • 現在のスキーマと別のスキーマのテーブル → OWNER.TABLE_NAME 形式で指定
  • セッションのデフォルトスキーマが変わっている → ALTER SESSION SET CURRENT_SCHEMA = HR;

Q2. DBA_TABLESにアクセスできないと言われます

SELECT_CATALOG_ROLE または SELECT ANY DICTIONARY 権限が必要です。DBA権限のあるユーザーで以下を実行:

GRANT SELECT_CATALOG_ROLE TO your_user;

権限がない場合は ALL_TABLES を使ってください。

Q3. ALL_TABLESに同じテーブルが何度も出る

複数のスキーマ(OWNER)から同名のテーブルにアクセス権が付与されている場合に発生します。OWNER 列で区別してください。

SELECT OWNER, TABLE_NAME FROM ALL_TABLES WHERE TABLE_NAME = 'EMPLOYEES';

Q4. テーブル一覧の取得が遅いです

DBA_TABLESに対するクエリは大規模DBでは数十秒かかることがあります。対策:

  • 不要な結合を避ける(コメント等を含めない単純なクエリにする)
  • OWNER で絞り込んでから他のテーブルと結合する
  • 結果が変わらない用途なら、結果をキャッシュ・テンポラリテーブルに保存して再利用

Q5. NUM_ROWSが実際の件数と違うのですが?

NUM_ROWS統計情報収集時点での概算値 です。最新化するには:

EXEC DBMS_STATS.GATHER_TABLE_STATS('HR', 'EMPLOYEES');
-- または全スキーマ
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('HR');


ただし、統計収集も負荷がかかるため、本番環境では定期実行のタイミングを考慮してください。

Q6. テーブル名に日本語が使われていますが取得できますか?

可能です。Oracleはマルチバイト文字をサポートしています。ただしテーブル名に日本語を使うとSQL記述時に二重引用符が必要になり、移植性が下がるため非推奨です。

Q7. テーブル一覧をExcelに出力したいです

SQL Developerが最も簡単です:

  1. 一覧取得SQLを実行
  2. 結果セット右クリック→「エクスポート」→形式に「xlsx」を選択

SQL*Plusしか使えない場合はCSVで出力 → Excelで開く手順になります。

Q8. 「ごみ箱」にあるテーブルも含まれていますか?

USER_TABLES等にはRecycle Bin内のテーブルも含まれます。除外したい場合:

SELECT TABLE_NAME 
FROM USER_TABLES 
WHERE TABLE_NAME NOT LIKE 'BIN$%';

または:

SELECT OBJECT_NAME 
FROM USER_OBJECTS 
WHERE OBJECT_TYPE = 'TABLE' 
  AND GENERATED = 'N';

Q9. テーブル一覧と同時にテーブルスペース情報も知りたいです

SELECT TABLE_NAME, TABLESPACE_NAME, STATUS, LOGGING 
FROM USER_TABLES 
ORDER BY TABLESPACE_NAME, TABLE_NAME;

Q10. リードレプリカ(Standby DB)でテーブル一覧は取得できますか?

可能です。Data Guardのフィジカル・スタンバイ(Read-Only Open状態)でも、データディクショナリビューは同様に参照できます。スタンバイ専用ビューもあり、運用状況を確認できます。


まとめ

Oracle Databaseでのテーブル一覧取得は、目的と権限に応じて使い分けることが重要です。

  • 基本3ビューを使い分け: USER_TABLES / ALL_TABLES / DBA_TABLES
  • マルチテナント: CDB_TABLES を使い CON_ID で区別
  • 実務クエリ: テーブルサイズは DBA_SEGMENTS、件数は NUM_ROWS、関連情報はビュー結合
  • システムテーブル除外: ORACLE_MAINTAINED = 'N' が安全
  • GUIならSQL Developer: フィルタ機能で大量テーブルでも素早く絞り込み
  • CSV出力: SQL*Plusの SET MARKUP CSV ON または SQL Developerのエクスポート

これらのSQLは、業務での「テーブル棚卸し」「容量管理」「データ移行準備」「セキュリティ監査」などあらゆる場面で活用できます。本記事のクエリを社内Wikiやスニペット集に登録しておくと、必要な時にすぐ取り出せて便利です。


本記事は2026年6月時点の情報をもとに、Oracle Database 19c / 21c / 23ai / 26ai での動作確認・公式ドキュメントに基づき作成しています。バージョンによって一部ビューの列構成が異なる場合があるため、最新の情報はOracle公式ドキュメントもあわせてご確認ください。