CONTAINERS句で複数PDBを一括参照!

CDB/PDB(マルチテナント)

C##ユーザー作成からORA-00942対処まで完全解説

OracleのCDB環境では、CONTAINERS()句を使用することで、複数のPDBにある同名の表をCDB$ROOTから一括参照することが可能です。

この記事では、以下のステップでC##USER1という共通ユーザーを作成し、emp_info表をPDB01PDB02に用意して、CONTAINERS句で一括参照する手順を詳しく解説します。

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


📌 構成概要

CDB$ROOT
└─ 共通ユーザー C##USER1
└─ emp_info表(構造のみ)

PDB01 / PDB02
└─ 共通ユーザー C##USER1
└─ emp_info表(同構造+各PDBごとのデータ)

↓ CDB$ROOTから CONTAINERS(C##USER1.emp_info) で一括参照

✅ Step1:共通ユーザー C##USER1 の作成と権限・クォータ付与

-- CDB$ROOTで実行
CREATE USER C##USER1 IDENTIFIED BY oracle CONTAINER=ALL;

GRANT CREATE SESSION, CREATE TABLE TO C##USER1 CONTAINER=ALL;

ALTER USER C##USER1 QUOTA UNLIMITED ON USERS CONTAINER=ALL;

CONTAINER=ALLを指定することで、全PDBに共通ユーザーが作成されます。


✅ Step2:各PDBでemp_info表を作成・データ挿入

🔹 PDB01

ALTER SESSION SET CONTAINER = PDB01;

CREATE TABLE C##USER1.emp_info (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
dept VARCHAR2(50)
);

INSERT INTO C##USER1.emp_info VALUES (1, '田中太郎', '営業');
INSERT INTO C##USER1.emp_info VALUES (2, '佐藤花子', '開発');
COMMIT;

🔹 PDB02

ALTER SESSION SET CONTAINER = PDB02;

CREATE TABLE C##USER1.emp_info (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
dept VARCHAR2(50)
);

INSERT INTO C##USER1.emp_info VALUES (3, '鈴木一郎', '経理');
INSERT INTO C##USER1.emp_info VALUES (4, '山本真由', '総務');
COMMIT;

⚠️ Step3:CDB$ROOTにも同名の表(構造のみ)を作成する

CONTAINERS()句を使うには、CDB$ROOTにも対象の表が存在している必要があります

ALTER SESSION SET CONTAINER = CDB$ROOT;

CREATE TABLE C##USER1.emp_info (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100),
dept VARCHAR2(50)
);

データは不要ですが、構造は各PDBと同一である必要があります


✅ Step4:CDB$ROOTからCONTAINERS句で参照

-- CDB$ROOTにて
SELECT con_id, emp_id, emp_name, dept
FROM CONTAINERS(C##USER1.emp_info);

📋 実行結果(例)

CON_IDEMP_IDEMP_NAMEDEPT
31田中太郎営業
32佐藤花子開発
43鈴木一郎経理
44山本真由総務
SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT
SQL> CREATE USER C##USER1 IDENTIFIED BY oracle CONTAINER=ALL;

ユーザーが作成されました。

SQL> GRANT CREATE SESSION, CREATE TABLE TO C##USER1 CONTAINER=ALL;

権限付与が成功しました。

SQL> ALTER USER C##USER1 QUOTA UNLIMITED ON USERS CONTAINER=ALL;

ユーザーが変更されました。

SQL> ALTER SESSION SET CONTAINER = PDB01;

セッションが変更されました。

SQL> show con_name

CON_NAME
------------------------------
PDB01
SQL> CREATE TABLE C##USER1.emp_info (
2 emp_id NUMBER PRIMARY KEY,
3 emp_name VARCHAR2(100),
4 dept VARCHAR2(50)
5 );

表が作成されました。

SQL> INSERT INTO C##USER1.emp_info VALUES (1, '田中太郎', '営業');

1行が作成されました。

SQL> INSERT INTO C##USER1.emp_info VALUES (2, '佐藤花子', '開発');

1行が作成されました。

SQL> COMMIT;

コミットが完了しました。

SQL> ALTER SESSION SET CONTAINER = PDB02;

セッションが変更されました。

SQL> show con_name

CON_NAME
------------------------------
PDB02
SQL> CREATE TABLE C##USER1.emp_info (
2 emp_id NUMBER PRIMARY KEY,
3 emp_name VARCHAR2(100),
4 dept VARCHAR2(50)
5 );

表が作成されました。

SQL> INSERT INTO C##USER1.emp_info VALUES (3, '鈴木一郎', '経理');

1行が作成されました。

SQL> INSERT INTO C##USER1.emp_info VALUES (4, '山本真由', '総務');

1行が作成されました。

SQL> COMMIT;

コミットが完了しました。

SQL> ALTER SESSION SET CONTAINER = CDB$ROOT;

セッションが変更されました。

SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT
SQL> CREATE TABLE C##USER1.emp_info (
2 emp_id NUMBER PRIMARY KEY,
3 emp_name VARCHAR2(100),
4 dept VARCHAR2(50)
5 );

表が作成されました。

SQL> set lin 1000 pages 1000
SQL> col emp_name for a30
SQL> col dept for a20
SQL> SELECT con_id, emp_id, emp_name, dept
2 FROM CONTAINERS(C##USER1.emp_info);

CON_ID EMP_ID EMP_NAME DEPT
---------- ---------- ------------------------------ --------------------
3 1 田中太郎 営業
3 2 佐藤花子 開発
4 3 鈴木一郎 経理
4 4 山本真由 総務

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


🔍 PDB名との対応を確認するSQL

SELECT con_id, pdb_name FROM dba_pdbs;

📝 テキスト図:CONTAINERS句の仕組み

                    +---------------------+
| CDB$ROOT |
| C##USER1.emp_info | ←★構造だけ必要
+---------------------+
|
-------------------------------------------------
| |
+--------+ +--------+
| PDB01 | | PDB02 |
+--------+ +--------+
| C##USER1.emp_info(データあり) | C##USER1.emp_info(データあり)|
+--------+ +--------+
|
CONTAINERS(C##USER1.emp_info)

✅ よくあるエラーと対策

エラー原因対策
ORA-00942: 表またはビューが存在しませんCDB$ROOTに対象表が存在していないCDB$ROOTでも同じ構造の表をCREATE TABLEする
ORA-01950: 表領域に対する権限がありませんUSERS表領域へのQUOTAが設定されていないALTER USER C##USER1 QUOTA UNLIMITED ON USERS CONTAINER=ALL;

✅ まとめ

ステップ内容
共通ユーザーC##USER1を作成し、権限と表領域QUOTAを付与
PDB01PDB02に同じ構造の表を作成し、データを挿入
CDB$ROOTにも構造だけの表を作成(CONTAINERS句の必須要件)
CONTAINERS()句で複数PDBの表を一括参照


[参考]
4 CDBの作成および構成

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

タイトルとURLをコピーしました