Oracle Databaseで「現在接続しているユーザーが所有する表を一覧で確認したい」ときによく使われるのが、データ・ディクショナリ・ビューのUSER_TABLESです。
USER_TABLESを参照すると、現在のユーザーが所有しているリレーショナル表の情報を確認できます。単に表名だけを知りたい場合はTABLE_NAME列を取得すればよく、表領域や行数統計などの情報も必要に応じて確認できます。
この記事では、USER_TABLESで何が確認できるのか、基本SQL、USER_TABLES・ALL_TABLES・DBA_TABLESの違い、シノニムやビューとの混同ポイントまで整理して解説します。
- USER_TABLESとは何か
- 接続ユーザーが所有する表名だけを一覧表示するSQL
- 「接続ユーザー」と「所有者」の関係を理解する
- USER_TABLESとALL_TABLESの違い
- USER_TABLESとDBA_TABLESの違い
- USER_TABLESにOWNER列がない理由
- USER_TABLESでは表名以外の情報も確認できる
- USER_TABLESに出てこないオブジェクトもある
- シノニム経由で参照できる表はUSER_TABLESに表示されるとは限らない
- 一時表もUSER_TABLESで確認できる場合がある
- 表名を条件指定して探す方法
- 現在の接続ユーザー自体を確認したい場合
- 資格試験ではUSER・ALL・DBAの意味をセットで覚える
- USER_TABLESは「自分がSELECTできる表一覧」ではない
- Oracle公式ドキュメントで定義を確認する
- まとめ:USER_TABLESで現在のユーザーが所有する表を確認できる
USER_TABLESとは何か
USER_TABLESは、現在のユーザーが所有しているリレーショナル表に関する情報を表示するOracleのデータ・ディクショナリ・ビューです。
したがって、ログイン中のユーザー自身が所有する表を調べる目的であれば、基本的にUSER_TABLESを使えます。
たとえば接続ユーザーがAPPUSERであり、そのスキーマにEMPLOYEES、DEPARTMENTS、SALESという表が存在する場合、USER_TABLESを検索するとそれらの表情報を取得できます。
接続ユーザーが所有する表名だけを一覧表示するSQL
表名だけを確認したい場合は、次のSQLが基本です。
SELECT TABLE_NAME
FROM USER_TABLES
ORDER BY TABLE_NAME;
このSQLを実行すると、現在接続しているユーザーが所有する表名がアルファベット順で表示されます。
たとえば結果は次のようになります。
TABLE_NAME
--------------------
DEPARTMENTS
EMPLOYEES
SALES
所有者名をWHERE句へ指定する必要はありません。USER_TABLESは、もともと現在のユーザーに対応する情報だけを表示するビューだからです。
「接続ユーザー」と「所有者」の関係を理解する
Oracleでは、ユーザーとスキーマは密接に関係しています。一般的な理解として、ユーザーを作成すると同名のスキーマが対応し、そのユーザーが作成した表などのオブジェクトはそのスキーマに属します。
たとえばSCOTTユーザーで接続し、SCOTTが所有する表をUSER_TABLESから確認する場合、表示対象はSCOTTスキーマの表です。
一方、SCOTTに別ユーザーの表を参照する権限が与えられていても、その表がSCOTT所有でなければUSER_TABLESには表示されません。ここが重要なポイントです。
USER_TABLESとALL_TABLESの違い
ALL_TABLESは、現在のユーザーからアクセスできる表の情報を表示するビューです。自分が所有する表だけでなく、権限によって参照可能な他スキーマの表も対象になる場合があります。
たとえばAPPUSERが自分のSALES表を所有し、HRユーザーのEMPLOYEES表にSELECT権限を持っている場合、USER_TABLESではAPPUSER所有の表だけが対象ですが、ALL_TABLESではアクセス可能なHR.EMPLOYEESも確認できます。
ALL_TABLESでは所有者を表すOWNER列も使えます。
SELECT OWNER, TABLE_NAME
FROM ALL_TABLES
ORDER BY OWNER, TABLE_NAME;
そのため、「自分の表だけを調べる」ならUSER_TABLES、「自分からアクセス可能な表まで調べる」ならALL_TABLESという使い分けが基本です。
USER_TABLESとDBA_TABLESの違い
DBA_TABLESは、データベース内のリレーショナル表に関する情報を広く確認するためのデータ・ディクショナリ・ビューです。
ただし、DBA_TABLESを参照するには通常、それに必要な管理権限やデータ・ディクショナリ参照権限が必要です。一般ユーザーが必ず参照できるとは限りません。
違いを簡単にまとめると次のようになります。
| ビュー | 主な対象 | OWNER列 |
|---|---|---|
| USER_TABLES | 現在のユーザーが所有する表 | なし |
| ALL_TABLES | 現在のユーザーがアクセスできる表 | あり |
| DBA_TABLES | データベース内の表 | あり |
Oracleの資格試験でも、このUSER・ALL・DBA系データ・ディクショナリ・ビューの違いはよく整理しておきたいポイントです。
USER_TABLESにOWNER列がない理由
USER_TABLESには通常、所有者を表すOWNER列はありません。
これはUSER_TABLESに表示される表の所有者が、現在のユーザーに限定されているためです。所有者が最初から決まっているので、OWNER列を持たせる必要がありません。
一方、ALL_TABLESやDBA_TABLESでは複数のスキーマの表が表示される可能性があるため、どのユーザーが所有している表なのかを識別するOWNER列があります。
USER_TABLESでは表名以外の情報も確認できる
USER_TABLESにはTABLE_NAME以外にも多数の列があります。表の管理情報や統計情報を確認するときにも利用できます。
たとえば表名と表領域名を確認するなら、次のように記述できます。
SELECT TABLE_NAME, TABLESPACE_NAME
FROM USER_TABLES
ORDER BY TABLE_NAME;
また、統計情報が収集されている場合はNUM_ROWSなどを確認することもできます。
SELECT TABLE_NAME, NUM_ROWS
FROM USER_TABLES
ORDER BY TABLE_NAME;
ただしNUM_ROWSは通常、リアルタイムにCOUNT(*)した値そのものではなく、オプティマイザ統計に基づく値です。実際の現在行数を必ず表すとは限らない点に注意が必要です。
USER_TABLESに出てこないオブジェクトもある
USER_TABLESという名前から、「ユーザーが所有しているすべてのオブジェクトが出る」と考えると誤解につながります。USER_TABLESは表に関するビューであり、ビュー、索引、シーケンスなどは別のデータ・ディクショナリ・ビューで確認します。
たとえばユーザーが所有するビューならUSER_VIEWS、索引ならUSER_INDEXES、シーケンスならUSER_SEQUENCESなどがあります。
所有オブジェクト全般を調べたい場合にはUSER_OBJECTSが便利です。
SELECT OBJECT_NAME, OBJECT_TYPE
FROM USER_OBJECTS
ORDER BY OBJECT_TYPE, OBJECT_NAME;
そのため、「表の一覧」と「データベースオブジェクト全体の一覧」は分けて考える必要があります。
シノニム経由で参照できる表はUSER_TABLESに表示されるとは限らない
Oracleでは、シノニムを使って別スキーマの表を短い名前で参照できることがあります。
たとえばHRユーザーが所有するHR.EMPLOYEESに対して、APPUSERからEMPLOYEESというシノニムを利用できたとしても、その元の表の所有者がHRであればAPPUSERのUSER_TABLESにその表が自分の所有表として表示されるわけではありません。
シノニムを調べたい場合はUSER_SYNONYMSやALL_SYNONYMSなどを確認します。この違いを理解しておくと、「SELECTできるのにUSER_TABLESにはない」という状況を説明しやすくなります。
一時表もUSER_TABLESで確認できる場合がある
Oracleのグローバル一時表なども、表オブジェクトとしてデータ・ディクショナリに登録されます。
USER_TABLESには一時表かどうかを判断するためのTEMPORARY列などがあり、通常表と区別できます。
SELECT TABLE_NAME, TEMPORARY
FROM USER_TABLES
ORDER BY TABLE_NAME;
そのため、単にTABLE_NAMEだけを見るのではなく、表の性質を確認したい場合は関連する列も併せて参照するとよいでしょう。
表名を条件指定して探す方法
所有する表の中から特定の名前だけを探したい場合は、WHERE句を利用できます。
たとえば「EMP」で始まる表を探す場合は次のようにします。
SELECT TABLE_NAME
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'EMP%'
ORDER BY TABLE_NAME;
Oracleでは、引用符なしで作成したオブジェクト名は通常大文字としてデータ・ディクショナリに格納されます。そのため、一般的な表を検索するときは'emp%'ではなく'EMP%'とする点も覚えておくと便利です。
現在の接続ユーザー自体を確認したい場合
USER_TABLESを見る前に、現在どのユーザーで接続しているのか確認したいこともあります。
その場合は、たとえば次のSQLで確認できます。
SELECT USER FROM DUAL;
結果がAPPUSERなら、その状態でUSER_TABLESを検索したときに対象となるのはAPPUSERが所有する表です。
SQL Developer、SQLcl、SQL*Plusなどで複数の接続先を扱っている場合は、想定と違うユーザーで接続していないか確認するためにも役立ちます。
資格試験ではUSER・ALL・DBAの意味をセットで覚える
Oracleを学習するときは、USER_TABLESだけ単独で暗記するより、データ・ディクショナリ・ビューの接頭辞をまとめて理解すると効率的です。
- USER_:現在のユーザーが所有するオブジェクトに関する情報
- ALL_:現在のユーザーからアクセス可能なオブジェクトに関する情報
- DBA_:データベース全体に関する情報で、通常は適切な権限が必要
たとえばTABLESだけでなく、USER_INDEXES、ALL_INDEXES、DBA_INDEXESのように同じ考え方が使われるビューがあります。
この規則を理解しておけば、初めて見るデータ・ディクショナリ・ビューでも、どの範囲の情報を扱うのか推測しやすくなります。
USER_TABLESは「自分がSELECTできる表一覧」ではない
特に重要なのが、USER_TABLESは「接続ユーザーがアクセス可能な表一覧」ではなく、「接続ユーザーが所有する表の情報」を見るためのビューだという点です。
他のユーザーからSELECT権限を付与された表は利用できても、自分の所有物ではありません。そのような表まで含めて確認したい場合はALL_TABLESを利用します。
この「所有している」と「アクセスできる」の違いを理解しておけば、USER_TABLESとALL_TABLESを取り違えにくくなります。
Oracle公式ドキュメントで定義を確認する
Oracleのデータ・ディクショナリ・ビューはバージョンによって列が追加される場合があるため、細かな仕様を確認するときは使用中のOracle Databaseバージョンに対応する公式リファレンスを確認するのが確実です。
Oracle Database ReferenceではUSER_TABLESについて、現在のユーザーが所有するリレーショナル表を説明するビューとして定義されています。[参照] Oracle Database Reference「USER_TABLES」
関連するALL_TABLESについても、アクセス可能なリレーショナル表に関する情報として公式ドキュメントで確認できます。[参照] Oracle Database Reference「ALL_TABLES」
まとめ:USER_TABLESで現在のユーザーが所有する表を確認できる
Oracle Databaseでは、USER_TABLESを検索することで、現在接続しているユーザーが所有するリレーショナル表の情報を確認できます。表名だけならSELECT TABLE_NAME FROM USER_TABLES;で確認できます。
一方で、他スキーマの表を含めて自分がアクセス可能な表を調べる場合はALL_TABLES、データベース全体の表を管理者権限などで確認する場合はDBA_TABLESを利用します。
覚え方としては、USER=自分が所有、ALL=自分がアクセス可能、DBA=データベース全体と整理すると分かりやすくなります。
またUSER_TABLESは表専用のビューなので、ビューや索引、シノニムなど別種類のオブジェクトまで確認したい場合は、USER_VIEWS、USER_INDEXES、USER_SYNONYMS、USER_OBJECTSなど目的に合ったデータ・ディクショナリ・ビューを利用することが重要です。


コメント