【Oracle】ユーザ権限を確認する方法完全ガイド|システム権限・ロール・オブジェクト権限・スキーマ別・全SQL一覧

【Oracle】ユーザ権限を確認する方法 Oracle

Oracleデータベースで「このユーザーはどんな権限を持っているのか」「なぜこのテーブルにアクセスできないのか」と調べる場面は頻繁にあります。

しかしOracleの権限体系はシステム権限・ロール・オブジェクト権限の3層構造で、確認するビューも場面によって使い分けが必要です。さらにロールを経由して付与された権限はそのままでは一覧できないなど、落とし穴も多い。

この記事では、DBA権限がある管理者向けの確認方法から一般ユーザーが自分の権限を確認する方法まで、Oracleの権限確認に必要なSQLをすべて解説します。

この記事でわかること
・システム権限 / ロール / オブジェクト権限 それぞれの確認SQL
・一般ユーザーがDBA権限なしで自分の権限を確認する方法
・SESSION_PRIVSで「今この操作ができるか」を即時確認
・ロール経由の権限を再帰展開して洗い出す方法
・スキーマ全体の権限を一括で棚卸しするUNION ALLクエリ
・特定の権限を持つユーザーを逆引き検索する方法
スポンサーリンク
  1. Oracleの権限体系:3種類を理解する
  2. DBA_ / ALL_ / USER_ ビューの使い分け
  3. システム権限を確認する
    1. DBA_SYS_PRIVS|特定ユーザーのシステム権限(DBA用)
    2. USER_SYS_PRIVS|自分自身のシステム権限(DBA権限不要)
    3. よく使われるシステム権限の一覧
  4. ロール(付与されたロール)を確認する
    1. DBA_ROLE_PRIVS|特定ユーザーに付与されたロール(DBA用)
    2. USER_ROLE_PRIVS|自分のロール(DBA権限不要)
    3. 代表的なデフォルトロールの権限内容
  5. ロールに含まれる権限を確認する
    1. ROLE_SYS_PRIVS|ロールに含まれるシステム権限
    2. ROLE_TAB_PRIVS|ロールに含まれるオブジェクト権限
  6. オブジェクト権限を確認する
    1. DBA_TAB_PRIVS|特定ユーザーのオブジェクト権限(DBA用)
    2. USER_TAB_PRIVS|自分のオブジェクト権限(DBA権限不要)
    3. ALL_TAB_PRIVS|アクセス可能な全オブジェクトの権限
    4. DBA_COL_PRIVS|カラム単位の権限確認
  7. 現在のセッションで有効な権限を確認する(SESSION_PRIVS)
    1. SESSION_ROLES|現在有効なロール
  8. ロール経由の権限を再帰的に展開して確認する
    1. ユーザーのロールを階層的に展開する
    2. 特定ユーザーの全権限を階層込みで洗い出す(WITH句)
  9. スキーマ全体の権限を一括確認する(権限棚卸しSQL)
    1. 全権限を1クエリで表示するUNION ALL SQL
    2. スキーマ全ユーザーの権限サマリー
  10. 特定の権限を持つユーザーを逆引きで調べる
    1. 特定のシステム権限を持つユーザーを検索
    2. 特定のテーブルに権限があるユーザーを検索
    3. DBAロールを持つユーザーを確認
  11. 誰がGRANTしたか(付与者・grantor)を確認する
  12. 特定スキーマへのアクセス権限を確認する
    1. 特定スキーマのオブジェクトへの権限を保有するユーザー一覧
    2. 特定スキーマ全体のSELECT権限保有者
    3. スキーマ横断で各ユーザーのアクセス可能オブジェクト数を集計
  13. GRANT文と確認ビューの対応関係
  14. SYSDBA・SYSOPER 権限を持つユーザーを確認する
  15. ORA-01031: insufficient privileges が出たときの調査手順
    1. ステップ1:現在のセッションで有効な権限を確認
    2. ステップ2:対象オブジェクトへの権限を確認
    3. ステップ3:DBAに確認・付与を依頼するための情報収集
    4. ステップ4:ロールが無効になっていないか確認
  16. ケース別 ビュー早見表
  17. よくある質問
  18. まとめ
  19. あわせて読みたい

Oracleの権限体系:3種類を理解する

Oracleの権限は大きく3種類に分かれています。確認するビューが種類ごとに異なるため、まずこの分類を把握することが重要です。

種類 説明 確認ビュー(DBA用) 確認ビュー(一般ユーザー)
システム権限 DB全体の操作権限。CREATE TABLE, CREATE SESSIONなど DBA_SYS_PRIVS USER_SYS_PRIVS
ロール 複数権限の集合体。CONNECT, RESOURCE, DBAなど DBA_ROLE_PRIVS USER_ROLE_PRIVS
オブジェクト権限 特定テーブル・ビュー等への操作権限。SELECT, INSERTなど DBA_TAB_PRIVS USER_TAB_PRIVS
ポイント:ロール経由で付与された権限は DBA_SYS_PRIVS には表示されません。「なぜこの権限があるのか」を調べる場合は、DBA_ROLE_PRIVS でロールを確認し、さらに ROLE_SYS_PRIVS でロール内の権限を展開する必要があります。

DBA_ / ALL_ / USER_ ビューの使い分け

権限確認ビューには3つのプレフィックスがあります。どのビューを使えるかはログインユーザーの権限によって異なります。

プレフィックス 参照できる範囲 必要な権限 使う場面
DBA_ データベース全体(全ユーザー) DBA権限 または SELECT ANY DICTIONARY DBA・管理者が他ユーザーの権限を調査
ALL_ 自分がアクセスできるオブジェクト全体 不要 他スキーマのオブジェクトにアクセスできるか調べたい
USER_ 自分自身のオブジェクトのみ 不要 一般ユーザーが自分の権限を確認
注意:DBA権限のない一般ユーザーが DBA_SYS_PRIVS を参照しようとすると ORA-00942: 表またはビューが存在しません エラーになります。自分の権限確認には USER_ 系ビューまたは SESSION_PRIVS を使ってください。

システム権限を確認する

システム権限とは、データベース全体に対する操作権限です(CREATE TABLE, CREATE SESSION, DROP ANY TABLE など)。

DBA_SYS_PRIVS|特定ユーザーのシステム権限(DBA用)

DBA権限がある場合、DBA_SYS_PRIVS で任意ユーザーのシステム権限を確認できます。

-- ユーザー SCOTT のシステム権限を確認
SELECT grantee,
       privilege,
       admin_option
FROM   dba_sys_privs
WHERE  grantee = 'SCOTT'
ORDER BY privilege;

実行結果の例:

GRANTEE PRIVILEGE ADMIN_OPTION
SCOTT CREATE SESSION NO
SCOTT CREATE TABLE NO
SCOTT UNLIMITED TABLESPACE NO
カラム 意味
GRANTEE 権限が付与されているユーザー名またはロール名
PRIVILEGE 付与されているシステム権限名
ADMIN_OPTION YES = このユーザーが他のユーザーにも同じ権限を付与できる(GRANT OPTION付き)

USER_SYS_PRIVS|自分自身のシステム権限(DBA権限不要)

一般ユーザーが自分自身のシステム権限を確認する場合は USER_SYS_PRIVS を使います。WHERE句は不要です。

-- 自分自身のシステム権限を確認(WHERE不要)
SELECT username,
       privilege,
       admin_option
FROM   user_sys_privs
ORDER BY privilege;

よく使われるシステム権限の一覧

権限名 操作できる内容 付与先
CREATE SESSION データベースへの接続 全ユーザー必須
CREATE TABLE 自スキーマにテーブルを作成 開発ユーザー
CREATE ANY TABLE 任意スキーマにテーブルを作成 DBA向け
DROP ANY TABLE 任意スキーマのテーブルを削除 DBA向け(危険)
SELECT ANY TABLE 任意スキーマのテーブルを参照 バックアップ・監査ツール
UNLIMITED TABLESPACE 表領域の割り当て制限なし 管理ユーザー
CREATE VIEW ビューを作成 開発ユーザー
CREATE PROCEDURE プロシージャ・ファンクションを作成 開発ユーザー
CREATE SEQUENCE シーケンスを作成 開発ユーザー
CREATE TRIGGER トリガーを作成 開発ユーザー
SYSDBA DBの起動・停止・完全バックアップ DB管理者のみ

ロール(付与されたロール)を確認する

ロールとは複数の権限をまとめたものです。ユーザーにロールを付与することで、個々の権限を一つずつ付与する手間を省けます。

DBA_ROLE_PRIVS|特定ユーザーに付与されたロール(DBA用)

-- ユーザー SCOTT に付与されているロールを確認
SELECT grantee,
       granted_role,
       admin_option,
       default_role
FROM   dba_role_privs
WHERE  grantee = 'SCOTT'
ORDER BY granted_role;

実行結果の例:

GRANTEE GRANTED_ROLE ADMIN_OPTION DEFAULT_ROLE
SCOTT CONNECT NO YES
SCOTT RESOURCE NO YES
カラム 意味
GRANTED_ROLE 付与されているロール名
ADMIN_OPTION YES = このロールを他のユーザーに付与できる
DEFAULT_ROLE YES = ログイン時に自動で有効になるロール

USER_ROLE_PRIVS|自分のロール(DBA権限不要)

-- 自分に付与されているロールを確認
SELECT granted_role,
       admin_option,
       default_role
FROM   user_role_privs
ORDER BY granted_role;

代表的なデフォルトロールの権限内容

ロール名 含まれる主な権限 用途
CONNECT CREATE SESSION のみ(Oracle 10g以降) 接続専用ユーザー
RESOURCE CREATE TABLE, CREATE SEQUENCE, CREATE PROCEDURE など 開発ユーザー
DBA ほぼすべてのシステム権限(ADMIN OPTION付き) DB管理者
SELECT_CATALOG_ROLE DBA_ ビューの参照 監視・監査ユーザー
EXECUTE_CATALOG_ROLE DBMS_ パッケージの実行 運用スクリプト向け
豆知識:Oracle 10g以降、CONNECT ロールには CREATE SESSION のみが含まれます。古いドキュメントには CREATE TABLE なども含まれると書いてある場合がありますが、現在の本番環境では CONNECT だけ付与しても CREATE TABLE はできません。RESOURCE ロールも必要です。

ロールに含まれる権限を確認する

ユーザーに付与されているロールの中にどのような権限が含まれているかを確認します。

ROLE_SYS_PRIVS|ロールに含まれるシステム権限

-- RESOURCE ロールに含まれるシステム権限を確認
SELECT role,
       privilege,
       admin_option
FROM   role_sys_privs
WHERE  role = 'RESOURCE'
ORDER BY privilege;

実行結果の例(Oracle 12c以降):

ROLE PRIVILEGE ADMIN_OPTION
RESOURCE CREATE CLUSTER NO
RESOURCE CREATE INDEXTYPE NO
RESOURCE CREATE OPERATOR NO
RESOURCE CREATE PROCEDURE NO
RESOURCE CREATE SEQUENCE NO
RESOURCE CREATE TABLE NO
RESOURCE CREATE TRIGGER NO
RESOURCE CREATE TYPE NO

ROLE_TAB_PRIVS|ロールに含まれるオブジェクト権限

-- 特定のロールに含まれるオブジェクト権限を確認
SELECT role,
       owner,
       table_name,
       privilege,
       grantable
FROM   role_tab_privs
WHERE  role = 'ロール名'
ORDER BY owner, table_name;

オブジェクト権限を確認する

オブジェクト権限とは、特定のテーブル・ビュー・プロシージャなどに対する操作権限(SELECT, INSERT, UPDATE, DELETE, EXECUTE など)です。

DBA_TAB_PRIVS|特定ユーザーのオブジェクト権限(DBA用)

-- ユーザー SCOTT のオブジェクト権限を確認
SELECT grantee,
       owner,
       table_name,
       privilege,
       grantable,
       hierarchy
FROM   dba_tab_privs
WHERE  grantee = 'SCOTT'
ORDER BY owner, table_name, privilege;

実行結果の例:

GRANTEE OWNER TABLE_NAME PRIVILEGE GRANTABLE
SCOTT HR DEPARTMENTS SELECT YES
SCOTT HR EMPLOYEES INSERT NO
SCOTT HR EMPLOYEES SELECT NO
カラム 意味
GRANTABLE YES = WITH GRANT OPTIONで付与されており、他ユーザーにも同じ権限を付与できる
HIERARCHY YES = WITH HIERARCHY OPTIONで付与(オブジェクト階層に対して権限行使可能)

USER_TAB_PRIVS|自分のオブジェクト権限(DBA権限不要)

USER_TAB_PRIVS は、自分が付与された権限に加えて、自分が他ユーザーに付与した権限も表示されます。自分が受け取った権限だけに絞るには grantee でフィルタします。

-- 自分に付与されたオブジェクト権限を確認
SELECT owner,
       table_name,
       privilege,
       grantable
FROM   user_tab_privs
WHERE  grantee = USER  -- 自分自身のみ
ORDER BY owner, table_name;

ALL_TAB_PRIVS|アクセス可能な全オブジェクトの権限

ロール経由も含めて、自分がアクセスできるオブジェクトを網羅的に確認するには ALL_TAB_PRIVS が便利です。

-- 自分がSELECTできるテーブル一覧(ロール経由含む)
SELECT table_schema,
       table_name,
       privilege,
       grantor,
       grantee
FROM   all_tab_privs
WHERE  privilege = 'SELECT'
  AND  type = 'TABLE'
ORDER BY table_schema, table_name;

DBA_COL_PRIVS|カラム単位の権限確認

特定のカラムだけに権限が付与されている場合は DBA_COL_PRIVS で確認します。

-- ユーザー SCOTT のカラム権限を確認
SELECT grantee,
       owner,
       table_name,
       column_name,
       privilege,
       grantable
FROM   dba_col_privs
WHERE  grantee = 'SCOTT'
ORDER BY table_name, column_name;

現在のセッションで有効な権限を確認する(SESSION_PRIVS)

SESSION_PRIVS は、現在ログインしているユーザーが実際に行使できる権限をすべて表示します。直接付与のシステム権限に加え、有効なロール内の権限も展開されて表示されます。

SESSION_PRIVSが最も役に立つシーン:「このSQL文が実行できるか分からない」「権限エラーの原因を調べたい」など、今すぐ操作できるかを確認したいときは SESSION_PRIVS が一番手取り早い。DBA権限も不要。
-- 現在のセッションで使える権限をすべて表示
SELECT privilege
FROM   session_privs
ORDER BY privilege;

SESSION_ROLES|現在有効なロール

-- 現在のセッションで有効なロールを確認
SELECT role
FROM   session_roles
ORDER BY role;
ポイントSESSION_PRIVSDBA_SYS_PRIVS の結果が異なる場合があります。これはロールの有効・無効状態によるものです。SET ROLE コマンドでロールを無効化すると SESSION_PRIVS からそのロールの権限が消えますが、DBA_SYS_PRIVS の内容は変わりません。

ロール経由の権限を再帰的に展開して確認する

ロールは入れ子(ロールの中にロール)にできます。CONNECT BY を使った階層クエリで、ネストしたロールも含めてすべての権限を展開して確認できます。

ユーザーのロールを階層的に展開する

-- SCOTT のロールをすべて再帰展開(ロールのネストを含む)
SELECT LEVEL AS depth,
       LPAD(' ', 2*(LEVEL-1)) || granted_role AS role_tree,
       admin_option
FROM   dba_role_privs
START WITH grantee = 'SCOTT'
CONNECT BY PRIOR granted_role = grantee
ORDER SIBLINGS BY granted_role;

特定ユーザーの全権限を階層込みで洗い出す(WITH句)

WITH句の再帰クエリを使ってユーザー→ロール→ロールの中のロールと辿りながら、最終的なシステム権限をすべて展開します。

-- SCOTT のすべてのシステム権限(ロール経由含む)を展開
WITH role_tree (grantee) AS (
    -- アンカー:SCOTT に直接付与されたロール
    SELECT granted_role
    FROM   dba_role_privs
    WHERE  grantee = 'SCOTT'
    UNION ALL
    -- 再帰:ロールの中のロールを展開
    SELECT r.granted_role
    FROM   dba_role_privs r
    JOIN   role_tree rt ON r.grantee = rt.grantee
)
-- 直接付与のシステム権限
SELECT 'DIRECT' AS source, privilege
FROM   dba_sys_privs
WHERE  grantee = 'SCOTT'
UNION ALL
-- ロール経由のシステム権限
SELECT rt.grantee AS source, rsp.privilege
FROM   role_tree rt
JOIN   role_sys_privs rsp ON rsp.role = rt.grantee
ORDER BY 1, 2;
注意:ロールの循環参照(A→B→A)があると無限ループになる可能性があります。実際のOracle環境では循環参照は作れない仕様ですが、クエリを汎用化する場合は CYCLE 句を追加しておくと安全です。

スキーマ全体の権限を一括確認する(権限棚卸しSQL)

セキュリティ監査や権限の棚卸しでは、特定ユーザーが持つすべての権限(システム権限・ロール・オブジェクト権限)を1つのSQLで一覧したい場面があります。

全権限を1クエリで表示するUNION ALL SQL

-- SCOTT の全権限(システム権限・ロール・オブジェクト権限)を一覧
SELECT '1_システム権限'    AS 権限種別,
       privilege          AS 権限名,
       '--'               AS オブジェクト,
       admin_option       AS オプション
FROM   dba_sys_privs
WHERE  grantee = 'SCOTT'
UNION ALL
SELECT '2_ロール',
       granted_role,
       '--',
       admin_option
FROM   dba_role_privs
WHERE  grantee = 'SCOTT'
UNION ALL
SELECT '3_オブジェクト権限',
       privilege,
       owner || '.' || table_name,
       grantable
FROM   dba_tab_privs
WHERE  grantee = 'SCOTT'
ORDER BY 1, 2;

実行結果の例:

権限種別 権限名 オブジェクト オプション
1_システム権限 CREATE SESSION NO
1_システム権限 CREATE TABLE NO
2_ロール CONNECT NO
2_ロール RESOURCE NO
3_オブジェクト権限 SELECT HR.DEPARTMENTS YES
3_オブジェクト権限 INSERT HR.EMPLOYEES NO
3_オブジェクト権限 SELECT HR.EMPLOYEES NO

スキーマ全ユーザーの権限サマリー

DB全体で「誰がどのオブジェクトにアクセスできるか」を把握するクエリです。権限が過剰に付与されていないか確認できます。

-- DB全ユーザーのオブジェクト権限サマリー(DBA用)
SELECT grantee,
       owner,
       COUNT(*)              AS 権限数,
       LISTAGG(privilege, ',') WITHIN GROUP (ORDER BY privilege) AS 権限一覧
FROM   dba_tab_privs
WHERE  grantee NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
  AND  owner   NOT IN ('SYS', 'SYSTEM')
GROUP BY grantee, owner
ORDER BY grantee, owner;

特定の権限を持つユーザーを逆引きで調べる

「この権限を持っているのは誰か?」を調べるパターンです。セキュリティ調査や不審なアクセス調査に使います。

特定のシステム権限を持つユーザーを検索

-- CREATE TABLE 権限を持つユーザー
SELECT grantee, privilege, admin_option
FROM   dba_sys_privs
WHERE  privilege = 'CREATE TABLE'
ORDER BY grantee;

-- 危険な権限(ANY系)を持つユーザーを確認
SELECT grantee, privilege
FROM   dba_sys_privs
WHERE  privilege LIKE '%ANY%'
  AND  grantee NOT IN ('DBA', 'SYS', 'SYSTEM')
ORDER BY grantee, privilege;

特定のテーブルに権限があるユーザーを検索

-- HR.EMPLOYEES に SELECT 権限を持つユーザー
SELECT grantee, privilege, grantable
FROM   dba_tab_privs
WHERE  owner      = 'HR'
  AND  table_name = 'EMPLOYEES'
  AND  privilege  = 'SELECT'
ORDER BY grantee;

DBAロールを持つユーザーを確認

-- DBA ロールが付与されているユーザーを確認
SELECT grantee, admin_option
FROM   dba_role_privs
WHERE  granted_role = 'DBA'
ORDER BY grantee;

-- 強力なロールを持つユーザー全体
SELECT grantee, granted_role, admin_option
FROM   dba_role_privs
WHERE  granted_role IN ('DBA', 'SYSDBA', 'SYSOPER')
ORDER BY granted_role, grantee;
セキュリティ監査でのポイントANY が付く権限(SELECT ANY TABLE, DROP ANY TABLE など)は非常に強力です。本番環境でこれらが業務ユーザーに付与されていないかを定期的に確認することを推奨します。

誰がGRANTしたか(付与者・grantor)を確認する

権限が誰によって付与されたかを調べるには、grantor カラムを使います。セキュリティインシデントの調査や権限の管理責任を追跡する場面で役立ちます。

-- SCOTT への権限の付与者(grantor)を確認
SELECT grantee,
       grantor,
       owner,
       table_name,
       privilege,
       grantable
FROM   dba_tab_privs
WHERE  grantee = 'SCOTT'
ORDER BY grantor, table_name;
注意DBA_SYS_PRIVS にはシステム権限の付与者(grantor)カラムがありません。システム権限の付与経緯はOracle監査機能(DBA_AUDIT_TRAIL)でのみ追跡可能です。

特定スキーマへのアクセス権限を確認する

「スキーマAのオブジェクトに誰がアクセスできるか」を確認するシナリオです。マルチスキーマ運用やセキュリティ設計の確認に使います。

特定スキーマのオブジェクトへの権限を保有するユーザー一覧

-- HRスキーマのオブジェクトにアクセス権限を持つユーザーを確認
SELECT grantee,
       table_name,
       privilege,
       grantable
FROM   dba_tab_privs
WHERE  owner = 'HR'
ORDER BY table_name, grantee;

特定スキーマ全体のSELECT権限保有者

-- HRスキーマにSELECT権限を持つ全ユーザーと対象テーブル
SELECT grantee,
       table_name,
       grantable
FROM   dba_tab_privs
WHERE  owner     = 'HR'
  AND  privilege = 'SELECT'
  AND  grantee NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
ORDER BY grantee, table_name;

スキーマ横断で各ユーザーのアクセス可能オブジェクト数を集計

-- ユーザーごとにアクセス可能なスキーマ・テーブル数をサマリー
SELECT grantee,
       owner             AS スキーマ,
       COUNT(DISTINCT table_name) AS テーブル数,
       LISTAGG(DISTINCT privilege, ',') WITHIN GROUP (ORDER BY privilege) AS 権限種別
FROM   dba_tab_privs
WHERE  grantee NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
GROUP BY grantee, owner
ORDER BY grantee, owner;
スキーマ権限の確認ポイント:スキーマとユーザーはOracleでは同義です(ユーザーを作成するとそのユーザー名のスキーマが自動作成されます)。別スキーマのオブジェクトへのアクセスはオブジェクト権限(DBA_TAB_PRIVS)またはロール(DBA_ROLE_PRIVS)で管理されます。

GRANT文と確認ビューの対応関係

「どのGRANT文で付与した権限がどのビューで確認できるか」の対応表です。付与側と確認側を一致させて理解することで、権限管理がスムーズになります。

GRANTの種類 GRANT文の例 確認ビュー(DBA) 確認ビュー(一般)
システム権限の付与 GRANT CREATE TABLE TO SCOTT; DBA_SYS_PRIVS USER_SYS_PRIVS
ロールの付与 GRANT CONNECT TO SCOTT; DBA_ROLE_PRIVS USER_ROLE_PRIVS
オブジェクト権限の付与 GRANT SELECT ON HR.EMPLOYEES TO SCOTT; DBA_TAB_PRIVS USER_TAB_PRIVS
WITH GRANT OPTION GRANT SELECT ON HR.EMP TO SCOTT WITH GRANT OPTION; DBA_TAB_PRIVS.GRANTABLE = 'YES' USER_TAB_PRIVS.GRANTABLE
WITH ADMIN OPTION GRANT CREATE TABLE TO SCOTT WITH ADMIN OPTION; DBA_SYS_PRIVS.ADMIN_OPTION = 'YES' USER_SYS_PRIVS.ADMIN_OPTION
カラム権限の付与 GRANT UPDATE(salary) ON HR.EMPLOYEES TO SCOTT; DBA_COL_PRIVS USER_COL_PRIVS

SYSDBA・SYSOPER 権限を持つユーザーを確認する

SYSDBASYSOPER はOSレベルの特権接続権限で、DBA_SYS_PRIVS には表示されません。V$PWFILE_USERS で確認します。

-- SYSDBA・SYSOPER 権限を持つユーザーを確認
SELECT username,
       sysdba,
       sysoper,
       sysasm,
       sysbackup,
       sysdg,
       syskm
FROM   v\$pwfile_users
ORDER BY username;

実行結果の例:

USERNAME SYSDBA SYSOPER SYSASM
SYS TRUE TRUE FALSE
SYSADMIN TRUE FALSE FALSE
注意V$PWFILE_USERS はパスワードファイル認証を使って接続する特権ユーザーの一覧です。OS認証のみで接続する場合はこのビューに表示されないことがあります。また Oracle 12c 以降は SYSBACKUPSYSDGSYSKM なども表示されます。

ORA-01031: insufficient privileges が出たときの調査手順

権限不足エラー(ORA-01031)が発生したとき、どの権限が不足しているかを特定する調査フローです。

ORA-01031 が発生するよくあるパターン
・テーブルへのSELECT/INSERT/UPDATE/DELETE権限がない
・ビュー経由でのアクセスに権限が不足している
・ストアドプロシージャ内でのDATA DICTIONARYアクセス
・ロールがデフォルト無効になっていて権限が有効化されていない

ステップ1:現在のセッションで有効な権限を確認

-- まず今の自分の権限を確認
SELECT privilege FROM session_privs ORDER BY privilege;
SELECT role FROM session_roles ORDER BY role;

ステップ2:対象オブジェクトへの権限を確認

-- 対象テーブルへの自分の権限を確認
SELECT owner, table_name, privilege, grantable
FROM   all_tab_privs
WHERE  grantee    IN (USER, 'PUBLIC')
  AND  table_name = 'EMPLOYEES'  -- エラーになったテーブル名
  AND  privilege  = 'SELECT';    -- 実行しようとした権限

ステップ3:DBAに確認・付与を依頼するための情報収集

-- 自分のユーザー名確認
SELECT USER FROM dual;

-- 不足している権限の確認(DBAが実行)
SELECT privilege, admin_option
FROM   dba_sys_privs
WHERE  grantee = 'SCOTT'  -- 自分のユーザー名
  AND  privilege LIKE '%TABLE%';

ステップ4:ロールが無効になっていないか確認

ロールは SET ROLE NONE を実行すると一時的に無効になります。セッション内でロールが無効化されていないかを確認します。

-- 付与されているロールと有効状態を比較
-- 付与ロール
SELECT granted_role FROM user_role_privs ORDER BY granted_role;

-- 現在有効なロール(SESSION_ROLESにないものは無効)
SELECT role FROM session_roles ORDER BY role;

-- ロールを有効化する
SET ROLE resource, connect;  -- 必要なロール名を指定
-- または全ロールを有効化
SET ROLE ALL;
ビュー経由のアクセスでよくあるハマりどころ:ビューに対するSELECT権限があっても、そのビューが参照する実テーブルに権限がない場合はアクセスできません(ビュー定義者の権限で動くため通常は問題ないが、CURRENT_USERスキームのビューでは呼び出し元の権限が必要な場合があります)。

ケース別 ビュー早見表

確認したい内容 DBA向けビュー 一般ユーザー向けビュー
システム権限 DBA_SYS_PRIVS USER_SYS_PRIVS
付与されたロール DBA_ROLE_PRIVS USER_ROLE_PRIVS
ロール内のシステム権限 ROLE_SYS_PRIVS ROLE_SYS_PRIVS(誰でも参照可)
ロール内のオブジェクト権限 ROLE_TAB_PRIVS ROLE_TAB_PRIVS(誰でも参照可)
オブジェクト権限(テーブル等) DBA_TAB_PRIVS USER_TAB_PRIVS
カラム単位の権限 DBA_COL_PRIVS USER_COL_PRIVS
今このセッションで使える権限 SESSION_PRIVS SESSION_PRIVS(誰でも参照可)
今このセッションで有効なロール SESSION_ROLES SESSION_ROLES(誰でも参照可)
アクセスできるオブジェクト全体 ALL_TAB_PRIVS ALL_TAB_PRIVS(誰でも参照可)

よくある質問

DBA_SYS_PRIVSに出てこない権限があるのはなぜ?
ロール経由で付与された権限は DBA_SYS_PRIVS に表示されません。DBA_ROLE_PRIVS でロールを確認し、ROLE_SYS_PRIVS でそのロールの中の権限を確認してください。セッションで有効な全権限を一度に確認するには SESSION_PRIVS が便利です。
SELECT ANY TABLE を付与したのに特定のテーブルが見れない
SELECT ANY TABLE はSYS所有のオブジェクトには効きません(Oracle 12c以降はさらに制限が強化)。SYSオブジェクトへのアクセスには SELECT_CATALOG_ROLE ロールまたは個別のGRANTが必要です。
一般ユーザーが他のユーザーの権限を確認したい
DBA_ 系ビューはDBA権限が必要ですが、SELECT ANY DICTIONARY 権限があれば一般ユーザーでも参照できます。ただし本番環境でこの権限を一般ユーザーに付与することはセキュリティリスクになるため、基本的にはDBA経由で確認するのが適切です。
DEFAULT_ROLE が NO のロールとは?
ログイン時に自動で有効にならないロールです。SET ROLE ロール名 コマンドを実行することで手動で有効化できます。これにより平常時は権限を制限し、必要なときだけ強力な権限を有効化するセキュリティ設計が可能です。
PUBLIC に付与された権限はどう確認する?
PUBLIC はすべてのユーザーが自動的に持つ擬似ユーザーです。DBA_SYS_PRIVS WHERE grantee = 'PUBLIC'DBA_TAB_PRIVS WHERE grantee = 'PUBLIC' で確認できます。Oracleインストール直後は多くの権限がPUBLICに付与されているため、定期的な監査が推奨されます。

まとめ

目的 使うビュー・手順
ユーザーのシステム権限を確認(DBA) DBA_SYS_PRIVS WHERE grantee = 'ユーザー名'
自分のシステム権限を確認 USER_SYS_PRIVS または SESSION_PRIVS
付与されたロールを確認 DBA_ROLE_PRIVS / USER_ROLE_PRIVS
ロール内の権限を確認 ROLE_SYS_PRIVS / ROLE_TAB_PRIVS
オブジェクト権限を確認 DBA_TAB_PRIVS / USER_TAB_PRIVS
カラム単位の権限を確認 DBA_COL_PRIVS / USER_COL_PRIVS
今すぐ使える権限を確認 SESSION_PRIVS
ロール経由の権限を再帰展開 CONNECT BY or WITH句の再帰クエリ
全権限を一括棚卸し UNION ALL で3ビューを結合するSQL
特定の権限を持つユーザーを逆引き DBA_SYS_PRIVS / DBA_TAB_PRIVS を権限名で絞り込み
定期的な権限棚卸しを推奨します:Oracleの権限は付与されると明示的にREVOKEしない限り残り続けます。特にANY系システム権限、DBAロールの付与状況は四半期に一度程度 DBA_SYS_PRIVS / DBA_ROLE_PRIVS で確認する運用を取り入れることを推奨します。

あわせて読みたい