【完全版】Oracle Databaseでテーブル一覧を取得する全方法
- 作成日 2026.06.09
- 更新日 2026.06.17
- 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本で完結します。
- 1. 結論:とにかく今すぐ知りたい人向けの3パターン
- 2. まず押さえるべき:USER_TABLES / ALL_TABLES / DBA_TABLES の違い
- 3. 基本パターン:シンプルなテーブル一覧取得
- 4. テーブル名で絞り込む(完全一致・部分一致)
- 5. システムテーブルを除外する
- 6. テーブル数を集計する
- 7. 【実践】テーブルサイズ込みで一覧取得する
- 8. テーブルの行数(件数)込みで一覧取得する
- 9. テーブルコメント込みで一覧取得する
- 10. カラム情報込みで一覧取得する
- 11. 主キー・外部キー込みで一覧取得する
- 12. インデックス情報込みで一覧取得する
- 13. テーブル種別で絞り込む
- 14. 最終更新日・アクセス日込みで一覧取得する
- 15. GUIツールでテーブル一覧を確認する
- 16. CSVファイルにテーブル一覧をエクスポートする
- 17. プログラム言語からテーブル一覧を取得する
- 18. 【応用】テーブル定義(DDL)を含めて取得する
- 19. ビューと一緒にオブジェクト一覧を取得する
- 20. CDB/PDB環境での注意点
- 21. 用途別:使い分けクイックリファレンス
- 22. よくある質問(FAQ)
- 22.1. Q1. USER_TABLESに表示されるのに、SELECTすると「ORA-00942: 表またはビューが存在しません」が出ます
- 22.2. Q2. DBA_TABLESにアクセスできないと言われます
- 22.3. Q3. ALL_TABLESに同じテーブルが何度も出る
- 22.4. Q4. テーブル一覧の取得が遅いです
- 22.5. Q5. NUM_ROWSが実際の件数と違うのですが?
- 22.6. Q6. テーブル名に日本語が使われていますが取得できますか?
- 22.7. Q7. テーブル一覧をExcelに出力したいです
- 22.8. Q8. 「ごみ箱」にあるテーブルも含まれていますか?
- 22.9. Q9. テーブル一覧と同時にテーブルスペース情報も知りたいです
- 22.10. Q10. リードレプリカ(Standby DB)でテーブル一覧は取得できますか?
- 23. まとめ
結論:とにかく今すぐ知りたい人向けの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_TABLES | CDB全体(全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
最も標準的な方法です:
- 接続を展開
- 「テーブル(フィルタ済)」を展開
- テーブル一覧が表示される
フィルタ機能の活用: 「テーブル」を右クリック→「フィルタの適用」で、特定の条件のみ表示可能。例: 名前が「EMP%」で始まるテーブルだけ表示。
レポート機能: 「表示」→「レポート」→「データ・ディクショナリ・レポート」→「ユーザー定義」→「自分のユーザーが所有するすべてのオブジェクト」で、より詳細な情報が確認できます。
A5:SQL Mk-2
国産の人気SQLクライアント:
- ツリーから対象データベースを展開
- スキーマを展開→「表」をクリック
- 右ペインにテーブル一覧が表示される
「表」を右クリック→「ER図にすべてのテーブルを追加」で、ER図形式で一覧できます。
Oracle SQL Developer Web(APEX付属)
ブラウザベースで動作するOracle純正ツール:
- SQL Workshop → Object Browser
- ドロップダウンから「Tables」を選択
- テーブル一覧が表示される
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を使った方法
- クエリを実行
- 結果セットを右クリック→「エクスポート」
- 形式に「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が最も簡単です:
- 一覧取得SQLを実行
- 結果セット右クリック→「エクスポート」→形式に「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公式ドキュメントもあわせてご確認ください。
-
前の記事
UbuntuでNASを自動マウントする設定方法を掲載中 2026.06.08
-
次の記事
Ubuntuでログファイルを効率よく確認する方法 | 効率よく確認する方法 2026.06.09
コメントを書く